/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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_telephony_telephony_h__ #define mozilla_dom_telephony_telephony_h__ #include "AudioChannelService.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/telephony/TelephonyCommon.h" #include "nsITelephonyCallInfo.h" #include "nsITelephonyService.h" // Need to include TelephonyCall.h because we have inline methods that // assume they see the definition of TelephonyCall. #include "TelephonyCall.h" class nsPIDOMWindow; namespace mozilla { namespace dom { namespace telephony { class TelephonyDialCallback; } // namespace telephony class OwningTelephonyCallOrTelephonyCallGroup; class Telephony final : public DOMEventTargetHelper, public nsIAudioChannelAgentCallback, private nsITelephonyListener { /** * Class Telephony doesn't actually expose nsITelephonyListener. * Instead, it owns an nsITelephonyListener derived instance mListener * and passes it to nsITelephonyService. The onreceived events are first * delivered to mListener and then forwarded to its owner, Telephony. See * also bug 775997 comment #51. */ class Listener; friend class telephony::TelephonyDialCallback; // The audio agent is needed to communicate with the audio channel service. nsCOMPtr mAudioAgent; nsCOMPtr mService; RefPtr mListener; nsTArray > mCalls; RefPtr mCallsList; RefPtr mGroup; RefPtr mReadyPromise; bool mIsAudioStartPlaying; bool mHaveDispatchedInterruptBeginEvent; bool mMuted; public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK NS_DECL_NSITELEPHONYLISTENER NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Telephony, DOMEventTargetHelper) nsPIDOMWindow* GetParentObject() const { return GetOwner(); } // WrapperCache virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; // WebIDL already_AddRefed Dial(const nsAString& aNumber, const Optional& aServiceId, ErrorResult& aRv); already_AddRefed DialEmergency(const nsAString& aNumber, const Optional& aServiceId, ErrorResult& aRv); already_AddRefed SendTones(const nsAString& aDTMFChars, uint32_t aPauseDuration, uint32_t aToneDuration, const Optional& aServiceId, ErrorResult& aRv); void StartTone(const nsAString& aDTMFChar, const Optional& aServiceId, ErrorResult& aRv); void StopTone(const Optional& aServiceId, ErrorResult& aRv); // In the audio channel architecture, the system app needs to know the state // of every audio channel, including the telephony. Therefore, when a // telephony call is activated , the audio channel service would notify the // system app about that. And we need an agent to communicate with the audio // channel service. We would follow the call states to make a correct // notification. void OwnAudioChannel(ErrorResult& aRv); bool GetMuted(ErrorResult& aRv) const; void SetMuted(bool aMuted, ErrorResult& aRv); bool GetSpeakerEnabled(ErrorResult& aRv) const; void SetSpeakerEnabled(bool aEnabled, ErrorResult& aRv); void GetActive(Nullable& aValue); already_AddRefed Calls() const; already_AddRefed ConferenceGroup() const; already_AddRefed GetReady(ErrorResult& aRv) const; IMPL_EVENT_HANDLER(incoming) IMPL_EVENT_HANDLER(callschanged) IMPL_EVENT_HANDLER(remoteheld) IMPL_EVENT_HANDLER(remoteresumed) static already_AddRefed Create(nsPIDOMWindow* aOwner, ErrorResult& aRv); void AddCall(TelephonyCall* aCall) { NS_ASSERTION(!mCalls.Contains(aCall), "Already know about this one!"); mCalls.AppendElement(aCall); NotifyCallsChanged(aCall); } void RemoveCall(TelephonyCall* aCall) { NS_ASSERTION(mCalls.Contains(aCall), "Didn't know about this one!"); mCalls.RemoveElement(aCall); NotifyCallsChanged(aCall); } nsITelephonyService* Service() const { return mService; } const nsTArray >& CallsArray() const { return mCalls; } private: explicit Telephony(nsPIDOMWindow* aOwner); ~Telephony(); void Shutdown(); static bool IsValidNumber(const nsAString& aNumber); static uint32_t GetNumServices(); static bool IsValidServiceId(uint32_t aServiceId); uint32_t GetServiceId(const Optional& aServiceId, bool aGetIfActiveCall = false); already_AddRefed DialInternal(uint32_t aServiceId, const nsAString& aNumber, bool aEmergency, ErrorResult& aRv); already_AddRefed CreateCallId(nsITelephonyCallInfo *aInfo); already_AddRefed CreateCallId(const nsAString& aNumber, uint16_t aNumberPresentation = nsITelephonyService::CALL_PRESENTATION_ALLOWED, const nsAString& aName = EmptyString(), uint16_t aNamePresentation = nsITelephonyService::CALL_PRESENTATION_ALLOWED); already_AddRefed CreateCall(TelephonyCallId* aId, uint32_t aServiceId, uint32_t aCallIndex, TelephonyCallState aState, bool aEmergency = false, bool aConference = false, bool aSwitchable = true, bool aMergeable = true); nsresult NotifyEvent(const nsAString& aType); nsresult NotifyCallsChanged(TelephonyCall* aCall); nsresult DispatchCallEvent(const nsAString& aType, TelephonyCall* aCall); already_AddRefed GetCall(uint32_t aServiceId, uint32_t aCallIndex); already_AddRefed GetCallFromEverywhere(uint32_t aServiceId, uint32_t aCallIndex); nsresult HandleCallInfo(nsITelephonyCallInfo* aInfo); // Check the call states to decide whether need to send the notificaiton. nsresult HandleAudioAgentState(); }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_telephony_telephony_h__