michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "Icc.h" michael@0: michael@0: #include "mozilla/dom/MozIccBinding.h" michael@0: #include "mozilla/dom/MozStkCommandEvent.h" michael@0: #include "nsIDOMDOMRequest.h" michael@0: #include "nsIDOMIccInfo.h" michael@0: #include "nsJSON.h" michael@0: #include "nsRadioInterfaceLayer.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: michael@0: using namespace mozilla::dom; michael@0: michael@0: Icc::Icc(nsPIDOMWindow* aWindow, long aClientId, const nsAString& aIccId) michael@0: : mLive(true) michael@0: , mClientId(aClientId) michael@0: , mIccId(aIccId) michael@0: { michael@0: SetIsDOMBinding(); michael@0: BindToOwner(aWindow); michael@0: michael@0: mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID); michael@0: michael@0: // Not being able to acquire the provider isn't fatal since we check michael@0: // for it explicitly below. michael@0: if (!mProvider) { michael@0: NS_WARNING("Could not acquire nsIIccProvider!"); michael@0: } michael@0: } michael@0: michael@0: void michael@0: Icc::Shutdown() michael@0: { michael@0: mProvider = nullptr; michael@0: mLive = false; michael@0: } michael@0: michael@0: nsresult michael@0: Icc::NotifyEvent(const nsAString& aName) michael@0: { michael@0: return DispatchTrustedEvent(aName); michael@0: } michael@0: michael@0: nsresult michael@0: Icc::NotifyStkEvent(const nsAString& aName, const nsAString& aMessage) michael@0: { michael@0: nsresult rv; michael@0: nsIScriptContext* sc = GetContextForEventHandlers(&rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: AutoPushJSContext cx(sc->GetNativeContext()); michael@0: JS::Rooted value(cx); michael@0: michael@0: if (!aMessage.IsEmpty()) { michael@0: nsCOMPtr json(new nsJSON()); michael@0: nsresult rv = json->DecodeToJSVal(aMessage, cx, &value); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } else { michael@0: value = JS::NullValue(); michael@0: } michael@0: michael@0: MozStkCommandEventInit init; michael@0: init.mBubbles = false; michael@0: init.mCancelable = false; michael@0: init.mCommand = value; michael@0: michael@0: nsRefPtr event = michael@0: MozStkCommandEvent::Constructor(this, aName, init); michael@0: michael@0: return DispatchTrustedEvent(event); michael@0: } michael@0: michael@0: // WrapperCache michael@0: michael@0: JSObject* michael@0: Icc::WrapObject(JSContext* aCx) michael@0: { michael@0: return MozIccBinding::Wrap(aCx, this); michael@0: } michael@0: michael@0: // MozIcc WebIDL michael@0: michael@0: already_AddRefed michael@0: Icc::GetIccInfo() const michael@0: { michael@0: if (!mProvider) { michael@0: return nullptr; michael@0: } michael@0: michael@0: nsCOMPtr iccInfo; michael@0: nsresult rv = mProvider->GetIccInfo(mClientId, getter_AddRefs(iccInfo)); michael@0: if (NS_FAILED(rv)) { michael@0: return nullptr; michael@0: } michael@0: michael@0: return iccInfo.forget(); michael@0: } michael@0: michael@0: void michael@0: Icc::GetCardState(nsString& aCardState) const michael@0: { michael@0: aCardState.SetIsVoid(true); michael@0: michael@0: if (!mProvider) { michael@0: return; michael@0: } michael@0: michael@0: nsresult rv = mProvider->GetCardState(mClientId, aCardState); michael@0: if (NS_FAILED(rv)) { michael@0: aCardState.SetIsVoid(true); michael@0: } michael@0: } michael@0: michael@0: void michael@0: Icc::SendStkResponse(const JSContext* aCx, JS::Handle aCommand, michael@0: JS::Handle aResponse, ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return; michael@0: } michael@0: michael@0: nsresult rv = mProvider->SendStkResponse(mClientId, GetOwner(), aCommand, michael@0: aResponse); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: } michael@0: } michael@0: michael@0: void michael@0: Icc::SendStkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested, michael@0: ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return; michael@0: } michael@0: michael@0: nsresult rv = mProvider->SendStkMenuSelection(mClientId, michael@0: GetOwner(), michael@0: aItemIdentifier, michael@0: aHelpRequested); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: } michael@0: } michael@0: michael@0: void michael@0: Icc::SendStkTimerExpiration(const JSContext* aCx, JS::Handle aTimer, michael@0: ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return; michael@0: } michael@0: michael@0: nsresult rv = mProvider->SendStkTimerExpiration(mClientId, GetOwner(), michael@0: aTimer); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: } michael@0: } michael@0: michael@0: void michael@0: Icc::SendStkEventDownload(const JSContext* aCx, JS::Handle aEvent, michael@0: ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return; michael@0: } michael@0: michael@0: nsresult rv = mProvider->SendStkEventDownload(mClientId, GetOwner(), aEvent); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: } michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::GetCardLock(const nsAString& aLockType, ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->GetCardLockState(mClientId, GetOwner(), aLockType, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::UnlockCardLock(const JSContext* aCx, JS::Handle aInfo, michael@0: ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->UnlockCardLock(mClientId, GetOwner(), aInfo, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::SetCardLock(const JSContext* aCx, JS::Handle aInfo, michael@0: ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->SetCardLock(mClientId, GetOwner(), aInfo, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::GetCardLockRetryCount(const nsAString& aLockType, ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->GetCardLockRetryCount(mClientId, michael@0: GetOwner(), michael@0: aLockType, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::ReadContacts(const nsAString& aContactType, ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->ReadContacts(mClientId, GetOwner(), aContactType, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::UpdateContact(const JSContext* aCx, const nsAString& aContactType, michael@0: JS::Handle aContact, const nsAString& aPin2, michael@0: ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->UpdateContact(mClientId, GetOwner(), aContactType, michael@0: aContact, aPin2, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::IccOpenChannel(const nsAString& aAid, ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->IccOpenChannel(mClientId, GetOwner(), aAid, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::IccExchangeAPDU(const JSContext* aCx, int32_t aChannel, michael@0: JS::Handle aApdu, ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->IccExchangeAPDU(mClientId, GetOwner(), aChannel, michael@0: aApdu, getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::IccCloseChannel(int32_t aChannel, ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->IccCloseChannel(mClientId, GetOwner(), aChannel, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: Icc::MatchMvno(const nsAString& aMvnoType, michael@0: const nsAString& aMvnoData, michael@0: ErrorResult& aRv) michael@0: { michael@0: if (!mProvider) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr request; michael@0: nsresult rv = mProvider->MatchMvno(mClientId, GetOwner(), michael@0: aMvnoType, aMvnoData, michael@0: getter_AddRefs(request)); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return nullptr; michael@0: } michael@0: michael@0: return request.forget(); michael@0: }