/* 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 DOM_MEDIA_WEBRTC_RTCDATACHANNEL_H_ #define DOM_MEDIA_WEBRTC_RTCDATACHANNEL_H_ #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/dom/Nullable.h" #include "mozilla/dom/RTCDataChannelBinding.h" #include "mozilla/dom/RTCStatsReportBinding.h" #include "mozilla/dom/TypedArray.h" #include "nsID.h" namespace mozilla { class DataChannel; namespace dom { class Blob; struct RTCStatsCollection; class StrongWorkerRef; class RTCDataChannel final : public DOMEventTargetHelper { public: RTCDataChannel(const nsACString& aLabel, const nsAString& aOrigin, bool aOrdered, Nullable aMaxLifeTime, Nullable aMaxRetransmits, const nsACString& aProtocol, bool aNegotiated, already_AddRefed& aDataChannel, nsPIDOMWindowInner* aWindow); nsresult Init(); NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RTCDataChannel, DOMEventTargetHelper) // EventTarget using EventTarget::EventListenerAdded; void EventListenerAdded(nsAtom* aType) override; using EventTarget::EventListenerRemoved; void EventListenerRemoved(nsAtom* aType) override; JSObject* WrapObject(JSContext*, JS::Handle aGivenProto) override; nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); } // WebIDL void GetLabel(nsACString& aLabel) const; void GetProtocol(nsACString& aProtocol) const; Nullable GetMaxPacketLifeTime() const; Nullable GetMaxRetransmits() const; RTCDataChannelState ReadyState() const; size_t BufferedAmount() const; size_t BufferedAmountLowThreshold() const; void SetBufferedAmountLowThreshold(size_t aThreshold); IMPL_EVENT_HANDLER(open) IMPL_EVENT_HANDLER(error) IMPL_EVENT_HANDLER(closing) IMPL_EVENT_HANDLER(close) void Close(); IMPL_EVENT_HANDLER(message) IMPL_EVENT_HANDLER(bufferedamountlow) RTCDataChannelType BinaryType() const { return mBinaryType; } void SetBinaryType(RTCDataChannelType aType) { mBinaryType = aType; } void Send(const nsAString& aData, ErrorResult& aRv); void Send(Blob& aData, ErrorResult& aRv); void Send(const ArrayBuffer& aData, ErrorResult& aRv); void Send(const ArrayBufferView& aData, ErrorResult& aRv); bool Negotiated() const; bool Ordered() const; Nullable GetId() const; // Transferable support, see // https://w3c.github.io/webrtc-pc/#transfering-a-data-channel // - Implementation of 'dataHolder' struct DataHolder { public: explicit DataHolder(const RTCDataChannel& aValue); ~DataHolder(); const RTCDataChannelState mReadyState; const nsCString mLabel; const bool mOrdered; const Nullable mMaxPacketLifeTime; const Nullable mMaxRetransmits; const nsCString mDataChannelProtocol; const bool mNegotiated; const Nullable mDataChannelId; const RefPtr mDataChannel; const double mMaxMessageSize; const nsString mOrigin; }; // - Implementation of the 'transfer steps' UniquePtr Transfer(); // - Implementation of the 'transfer receiving steps' explicit RTCDataChannel(nsIGlobalObject* aGlobal, const DataHolder& aDataHolder); nsresult DoOnMessageAvailable(const nsACString& aMessage, bool aBinary); void SetId(uint16_t aId); void SetMaxMessageSize(double aMaxMessageSize); void SetReadyState(const RTCDataChannelState aState); void AnnounceOpen(); void AnnounceClosed(); void GracefulClose(); void DecrementBufferedAmount(size_t aSize); dom::RTCDataChannelStats GetStats(const DOMHighResTimeStamp aTimestamp) const; void UnsetWorkerNeedsUs(); protected: ~RTCDataChannel(); private: nsresult OnSimpleEvent(const nsAString& aName); // if there are "strong event listeners" or outgoing not sent messages // then this method keeps the object alive when js doesn't have strong // references to it. void UpdateMustKeepAlive(); // ATTENTION, when calling this method the object can be released // (and possibly collected). void DontKeepAliveAnyMore(); void IncrementBufferedAmount(size_t aSize); bool CheckReadyState(ErrorResult& aRv); bool CheckSendSize(uint64_t aSize, ErrorResult& aRv) const; void DisableWorkerTransfer(); void ReleaseSelf(); const nsID mUuid; // Solely for stats. Probably overkill. const nsString mOrigin; const nsCString mLabel; const bool mOrdered; const Nullable mMaxPacketLifeTime; const Nullable mMaxRetransmits; const nsCString mDataChannelProtocol; const bool mNegotiated; // to keep us alive while we have listeners RefPtr mSelfRef; RefPtr mWorkerRef; // Owning reference const RefPtr mDataChannel; RTCDataChannelType mBinaryType = RTCDataChannelType::Arraybuffer; Nullable mDataChannelId; RTCDataChannelState mReadyState = RTCDataChannelState::Connecting; bool mWorkerNeedsUs = false; bool mCheckMustKeepAlive = true; bool mIsTransferable = true; double mMaxMessageSize = 0; RefPtr mEventTarget; size_t mBufferedAmount = 0; size_t mBufferedThreshold = 0; size_t mMessagesSent = 0; size_t mBytesSent = 0; size_t mMessagesReceived = 0; size_t mBytesReceived = 0; }; } // namespace dom } // namespace mozilla #endif // DOM_MEDIA_WEBRTC_RTCDATACHANNEL_H_