RTCDataChannel.h (5779B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef DOM_MEDIA_WEBRTC_RTCDATACHANNEL_H_ 8 #define DOM_MEDIA_WEBRTC_RTCDATACHANNEL_H_ 9 10 #include "mozilla/DOMEventTargetHelper.h" 11 #include "mozilla/dom/Nullable.h" 12 #include "mozilla/dom/RTCDataChannelBinding.h" 13 #include "mozilla/dom/RTCStatsReportBinding.h" 14 #include "mozilla/dom/TypedArray.h" 15 #include "nsID.h" 16 17 namespace mozilla { 18 class DataChannel; 19 20 namespace dom { 21 class Blob; 22 struct RTCStatsCollection; 23 class StrongWorkerRef; 24 25 class RTCDataChannel final : public DOMEventTargetHelper { 26 public: 27 RTCDataChannel(const nsACString& aLabel, const nsAString& aOrigin, 28 bool aOrdered, Nullable<uint16_t> aMaxLifeTime, 29 Nullable<uint16_t> aMaxRetransmits, 30 const nsACString& aProtocol, bool aNegotiated, 31 already_AddRefed<DataChannel>& aDataChannel, 32 nsPIDOMWindowInner* aWindow); 33 34 nsresult Init(); 35 36 NS_DECL_ISUPPORTS_INHERITED 37 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RTCDataChannel, DOMEventTargetHelper) 38 39 // EventTarget 40 using EventTarget::EventListenerAdded; 41 void EventListenerAdded(nsAtom* aType) override; 42 43 using EventTarget::EventListenerRemoved; 44 void EventListenerRemoved(nsAtom* aType) override; 45 46 JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) override; 47 nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); } 48 49 // WebIDL 50 void GetLabel(nsACString& aLabel) const; 51 void GetProtocol(nsACString& aProtocol) const; 52 Nullable<uint16_t> GetMaxPacketLifeTime() const; 53 Nullable<uint16_t> GetMaxRetransmits() const; 54 RTCDataChannelState ReadyState() const; 55 size_t BufferedAmount() const; 56 size_t BufferedAmountLowThreshold() const; 57 void SetBufferedAmountLowThreshold(size_t aThreshold); 58 IMPL_EVENT_HANDLER(open) 59 IMPL_EVENT_HANDLER(error) 60 IMPL_EVENT_HANDLER(closing) 61 IMPL_EVENT_HANDLER(close) 62 void Close(); 63 IMPL_EVENT_HANDLER(message) 64 IMPL_EVENT_HANDLER(bufferedamountlow) 65 RTCDataChannelType BinaryType() const { return mBinaryType; } 66 void SetBinaryType(RTCDataChannelType aType) { mBinaryType = aType; } 67 void Send(const nsAString& aData, ErrorResult& aRv); 68 void Send(Blob& aData, ErrorResult& aRv); 69 void Send(const ArrayBuffer& aData, ErrorResult& aRv); 70 void Send(const ArrayBufferView& aData, ErrorResult& aRv); 71 72 bool Negotiated() const; 73 bool Ordered() const; 74 Nullable<uint16_t> GetId() const; 75 76 // Transferable support, see 77 // https://w3c.github.io/webrtc-pc/#transfering-a-data-channel 78 79 // - Implementation of 'dataHolder' 80 struct DataHolder { 81 public: 82 explicit DataHolder(const RTCDataChannel& aValue); 83 ~DataHolder(); 84 const RTCDataChannelState mReadyState; 85 const nsCString mLabel; 86 const bool mOrdered; 87 const Nullable<uint16_t> mMaxPacketLifeTime; 88 const Nullable<uint16_t> mMaxRetransmits; 89 const nsCString mDataChannelProtocol; 90 const bool mNegotiated; 91 const Nullable<uint16_t> mDataChannelId; 92 const RefPtr<DataChannel> mDataChannel; 93 const double mMaxMessageSize; 94 const nsString mOrigin; 95 }; 96 97 // - Implementation of the 'transfer steps' 98 UniquePtr<DataHolder> Transfer(); 99 100 // - Implementation of the 'transfer receiving steps' 101 explicit RTCDataChannel(nsIGlobalObject* aGlobal, 102 const DataHolder& aDataHolder); 103 104 nsresult DoOnMessageAvailable(const nsACString& aMessage, bool aBinary); 105 106 void SetId(uint16_t aId); 107 void SetMaxMessageSize(double aMaxMessageSize); 108 void SetReadyState(const RTCDataChannelState aState); 109 110 void AnnounceOpen(); 111 void AnnounceClosed(); 112 void GracefulClose(); 113 114 void DecrementBufferedAmount(size_t aSize); 115 116 dom::RTCDataChannelStats GetStats(const DOMHighResTimeStamp aTimestamp) const; 117 118 void UnsetWorkerNeedsUs(); 119 120 protected: 121 ~RTCDataChannel(); 122 123 private: 124 nsresult OnSimpleEvent(const nsAString& aName); 125 126 // if there are "strong event listeners" or outgoing not sent messages 127 // then this method keeps the object alive when js doesn't have strong 128 // references to it. 129 void UpdateMustKeepAlive(); 130 // ATTENTION, when calling this method the object can be released 131 // (and possibly collected). 132 void DontKeepAliveAnyMore(); 133 134 void IncrementBufferedAmount(size_t aSize); 135 bool CheckReadyState(ErrorResult& aRv); 136 bool CheckSendSize(uint64_t aSize, ErrorResult& aRv) const; 137 void DisableWorkerTransfer(); 138 139 void ReleaseSelf(); 140 141 const nsID mUuid; // Solely for stats. Probably overkill. 142 const nsString mOrigin; 143 const nsCString mLabel; 144 const bool mOrdered; 145 const Nullable<uint16_t> mMaxPacketLifeTime; 146 const Nullable<uint16_t> mMaxRetransmits; 147 const nsCString mDataChannelProtocol; 148 const bool mNegotiated; 149 150 // to keep us alive while we have listeners 151 RefPtr<RTCDataChannel> mSelfRef; 152 RefPtr<StrongWorkerRef> mWorkerRef; 153 // Owning reference 154 const RefPtr<DataChannel> mDataChannel; 155 RTCDataChannelType mBinaryType = RTCDataChannelType::Arraybuffer; 156 157 Nullable<uint16_t> mDataChannelId; 158 RTCDataChannelState mReadyState = RTCDataChannelState::Connecting; 159 bool mWorkerNeedsUs = false; 160 bool mCheckMustKeepAlive = true; 161 bool mIsTransferable = true; 162 double mMaxMessageSize = 0; 163 RefPtr<nsISerialEventTarget> mEventTarget; 164 size_t mBufferedAmount = 0; 165 size_t mBufferedThreshold = 0; 166 size_t mMessagesSent = 0; 167 size_t mBytesSent = 0; 168 size_t mMessagesReceived = 0; 169 size_t mBytesReceived = 0; 170 }; 171 172 } // namespace dom 173 } // namespace mozilla 174 #endif // DOM_MEDIA_WEBRTC_RTCDATACHANNEL_H_