michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 "ipc/TelephonyIPCProvider.h" michael@0: michael@0: #include "mozilla/dom/ContentChild.h" michael@0: #include "mozilla/dom/telephony/TelephonyChild.h" michael@0: #include "mozilla/Preferences.h" michael@0: michael@0: USING_TELEPHONY_NAMESPACE michael@0: using namespace mozilla::dom; michael@0: michael@0: namespace { michael@0: michael@0: const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces"; michael@0: #define kPrefDefaultServiceId "dom.telephony.defaultServiceId" michael@0: const char* kObservedPrefs[] = { michael@0: kPrefDefaultServiceId, michael@0: nullptr michael@0: }; michael@0: michael@0: uint32_t michael@0: getDefaultServiceId() michael@0: { michael@0: int32_t id = mozilla::Preferences::GetInt(kPrefDefaultServiceId, 0); michael@0: int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1); michael@0: michael@0: if (id >= numRil || id < 0) { michael@0: id = 0; michael@0: } michael@0: michael@0: return id; michael@0: } michael@0: michael@0: } // Anonymous namespace michael@0: michael@0: NS_IMPL_ISUPPORTS(TelephonyIPCProvider, michael@0: nsITelephonyProvider, michael@0: nsITelephonyListener, michael@0: nsIObserver) michael@0: michael@0: TelephonyIPCProvider::TelephonyIPCProvider() michael@0: { michael@0: // Deallocated in ContentChild::DeallocPTelephonyChild(). michael@0: mPTelephonyChild = new TelephonyChild(this); michael@0: ContentChild::GetSingleton()->SendPTelephonyConstructor(mPTelephonyChild); michael@0: michael@0: Preferences::AddStrongObservers(this, kObservedPrefs); michael@0: mDefaultServiceId = getDefaultServiceId(); michael@0: } michael@0: michael@0: TelephonyIPCProvider::~TelephonyIPCProvider() michael@0: { michael@0: mPTelephonyChild->Send__delete__(mPTelephonyChild); michael@0: mPTelephonyChild = nullptr; michael@0: } michael@0: michael@0: /* michael@0: * Implementation of nsIObserver. michael@0: */ michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::Observe(nsISupports* aSubject, michael@0: const char* aTopic, michael@0: const char16_t* aData) michael@0: { michael@0: if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { michael@0: nsDependentString data(aData); michael@0: if (data.EqualsLiteral(kPrefDefaultServiceId)) { michael@0: mDefaultServiceId = getDefaultServiceId(); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: MOZ_ASSERT(false, "TelephonyIPCProvider got unexpected topic!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: /* michael@0: * Implementation of nsITelephonyProvider. michael@0: */ michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::GetDefaultServiceId(uint32_t* aServiceId) michael@0: { michael@0: *aServiceId = mDefaultServiceId; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::RegisterListener(nsITelephonyListener *aListener) michael@0: { michael@0: MOZ_ASSERT(!mListeners.Contains(aListener)); michael@0: michael@0: // nsTArray doesn't fail. michael@0: mListeners.AppendElement(aListener); michael@0: michael@0: if (mListeners.Length() == 1) { michael@0: mPTelephonyChild->SendRegisterListener(); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::UnregisterListener(nsITelephonyListener *aListener) michael@0: { michael@0: MOZ_ASSERT(mListeners.Contains(aListener)); michael@0: michael@0: // We always have the element here, so it can't fail. michael@0: mListeners.RemoveElement(aListener); michael@0: michael@0: if (!mListeners.Length()) { michael@0: mPTelephonyChild->SendUnregisterListener(); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: TelephonyIPCProvider::SendRequest(nsITelephonyListener *aListener, michael@0: nsITelephonyCallback *aCallback, michael@0: const IPCTelephonyRequest& aRequest) michael@0: { michael@0: // Life time of newly allocated TelephonyRequestChild instance is managed by michael@0: // IPDL itself. michael@0: TelephonyRequestChild* actor = new TelephonyRequestChild(aListener, aCallback); michael@0: mPTelephonyChild->SendPTelephonyRequestConstructor(actor, aRequest); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::EnumerateCalls(nsITelephonyListener *aListener) michael@0: { michael@0: return SendRequest(aListener, nullptr, EnumerateCallsRequest()); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::Dial(uint32_t aClientId, const nsAString& aNumber, michael@0: bool aIsEmergency, nsITelephonyCallback *aCallback) michael@0: { michael@0: return SendRequest(nullptr, aCallback, michael@0: DialRequest(aClientId, nsString(aNumber), aIsEmergency)); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::HangUp(uint32_t aClientId, uint32_t aCallIndex) michael@0: { michael@0: mPTelephonyChild->SendHangUpCall(aClientId, aCallIndex); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::AnswerCall(uint32_t aClientId, uint32_t aCallIndex) michael@0: { michael@0: mPTelephonyChild->SendAnswerCall(aClientId, aCallIndex); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::RejectCall(uint32_t aClientId, uint32_t aCallIndex) michael@0: { michael@0: mPTelephonyChild->SendRejectCall(aClientId, aCallIndex); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::HoldCall(uint32_t aClientId, uint32_t aCallIndex) michael@0: { michael@0: mPTelephonyChild->SendHoldCall(aClientId, aCallIndex); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::ResumeCall(uint32_t aClientId, uint32_t aCallIndex) michael@0: { michael@0: mPTelephonyChild->SendResumeCall(aClientId, aCallIndex); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::ConferenceCall(uint32_t aClientId) michael@0: { michael@0: mPTelephonyChild->SendConferenceCall(aClientId); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::SeparateCall(uint32_t aClientId, uint32_t aCallIndex) michael@0: { michael@0: mPTelephonyChild->SendSeparateCall(aClientId, aCallIndex); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::HoldConference(uint32_t aClientId) michael@0: { michael@0: mPTelephonyChild->SendHoldConference(aClientId); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::ResumeConference(uint32_t aClientId) michael@0: { michael@0: mPTelephonyChild->SendResumeConference(aClientId); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::StartTone(uint32_t aClientId, const nsAString& aDtmfChar) michael@0: { michael@0: mPTelephonyChild->SendStartTone(aClientId, nsString(aDtmfChar)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::StopTone(uint32_t aClientId) michael@0: { michael@0: mPTelephonyChild->SendStopTone(aClientId); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::GetMicrophoneMuted(bool* aMuted) michael@0: { michael@0: mPTelephonyChild->SendGetMicrophoneMuted(aMuted); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::SetMicrophoneMuted(bool aMuted) michael@0: { michael@0: mPTelephonyChild->SendSetMicrophoneMuted(aMuted); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::GetSpeakerEnabled(bool* aEnabled) michael@0: { michael@0: mPTelephonyChild->SendGetSpeakerEnabled(aEnabled); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::SetSpeakerEnabled(bool aEnabled) michael@0: { michael@0: mPTelephonyChild->SendSetSpeakerEnabled(aEnabled); michael@0: return NS_OK; michael@0: } michael@0: michael@0: // nsITelephonyListener michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::CallStateChanged(uint32_t aClientId, michael@0: uint32_t aCallIndex, michael@0: uint16_t aCallState, michael@0: const nsAString& aNumber, michael@0: bool aIsActive, michael@0: bool aIsOutgoing, michael@0: bool aIsEmergency, michael@0: bool aIsConference, michael@0: bool aIsSwitchable, michael@0: bool aIsMergeable) michael@0: { michael@0: for (uint32_t i = 0; i < mListeners.Length(); i++) { michael@0: mListeners[i]->CallStateChanged(aClientId, aCallIndex, aCallState, aNumber, michael@0: aIsActive, aIsOutgoing, aIsEmergency, michael@0: aIsConference, aIsSwitchable, aIsMergeable); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::ConferenceCallStateChanged(uint16_t aCallState) michael@0: { michael@0: for (uint32_t i = 0; i < mListeners.Length(); i++) { michael@0: mListeners[i]->ConferenceCallStateChanged(aCallState); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::EnumerateCallStateComplete() michael@0: { michael@0: MOZ_CRASH("Not a EnumerateCalls request!"); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::EnumerateCallState(uint32_t aClientId, michael@0: uint32_t aCallIndex, michael@0: uint16_t aCallState, michael@0: const nsAString& aNumber, michael@0: bool aIsActive, michael@0: bool aIsOutgoing, michael@0: bool aIsEmergency, michael@0: bool aIsConference, michael@0: bool aIsSwitchable, michael@0: bool aIsMergeable) michael@0: { michael@0: MOZ_CRASH("Not a EnumerateCalls request!"); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::NotifyCdmaCallWaiting(uint32_t aClientId, michael@0: const nsAString& aNumber) michael@0: { michael@0: for (uint32_t i = 0; i < mListeners.Length(); i++) { michael@0: mListeners[i]->NotifyCdmaCallWaiting(aClientId, aNumber); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::NotifyConferenceError(const nsAString& aName, michael@0: const nsAString& aMessage) michael@0: { michael@0: for (uint32_t i = 0; i < mListeners.Length(); i++) { michael@0: mListeners[i]->NotifyConferenceError(aName, aMessage); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::NotifyError(uint32_t aClientId, int32_t aCallIndex, michael@0: const nsAString& aError) michael@0: { michael@0: for (uint32_t i = 0; i < mListeners.Length(); i++) { michael@0: mListeners[i]->NotifyError(aClientId, aCallIndex, aError); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: TelephonyIPCProvider::SupplementaryServiceNotification(uint32_t aClientId, michael@0: int32_t aCallIndex, michael@0: uint16_t aNotification) michael@0: { michael@0: for (uint32_t i = 0; i < mListeners.Length(); i++) { michael@0: mListeners[i]->SupplementaryServiceNotification(aClientId, aCallIndex, michael@0: aNotification); michael@0: } michael@0: return NS_OK; michael@0: }