1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef _PEER_CONNECTION_IMPL_H_
6 #define _PEER_CONNECTION_IMPL_H_
14 #include "mozilla/RefPtr.h"
15 #include "nsComponentManagerUtils.h"
16 #include "nsPIDOMWindow.h"
17 #include "nsIUUIDGenerator.h"
18 #include "nsIThread.h"
19 #include "mozilla/Mutex.h"
20 #include "mozilla/Attributes.h"
22 // Work around nasty macro in webrtc/voice_engine/voice_engine_defines.h
27 #include "jsep/JsepSession.h"
28 #include "jsep/JsepSessionImpl.h"
29 #include "sdp/SdpMediaSection.h"
31 #include "mozilla/ErrorResult.h"
32 #include "jsapi/PacketDumper.h"
33 #include "mozilla/dom/RTCPeerConnectionBinding.h" // mozPacketDumpType, maybe move?
34 #include "mozilla/dom/PeerConnectionImplBinding.h" // ChainedOperation
35 #include "mozilla/dom/RTCRtpCapabilitiesBinding.h"
36 #include "mozilla/dom/RTCRtpTransceiverBinding.h"
37 #include "mozilla/dom/RTCConfigurationBinding.h"
38 #include "PrincipalChangeObserver.h"
39 #include "mozilla/dom/PromiseNativeHandler.h"
41 #include "mozilla/TimeStamp.h"
42 #include "mozilla/net/DataChannel.h"
43 #include "VideoUtils.h"
44 #include "VideoSegment.h"
45 #include "mozilla/dom/RTCStatsReportBinding.h"
46 #include "mozilla/PeerIdentity.h"
47 #include "RTCStatsIdGenerator.h"
48 #include "RTCStatsReport.h"
50 #include "mozilla/net/StunAddrsRequestChild.h"
51 #include "MediaEventSource.h"
52 #include "MediaTransportHandler.h"
53 #include "nsIHttpChannelInternal.h"
54 #include "RTCDtlsTransport.h"
55 #include "RTCRtpTransceiver.h"
58 #ifdef USE_FAKE_PCOBSERVER
59 class AFakePCObserver
;
63 class nsDOMDataChannel
;
71 class MediaPipelineReceive
;
72 class MediaPipelineTransmit
;
73 enum class PrincipalPrivacy
: uint8_t;
74 class SharedWebrtcState
;
78 struct RTCConfiguration
;
79 struct RTCRtpSourceEntry
;
81 struct RTCOfferOptions
;
82 struct RTCRtpParameters
;
84 class MediaStreamTrack
;
86 #ifdef USE_FAKE_PCOBSERVER
87 typedef test::AFakePCObserver PeerConnectionObserver
;
88 typedef const char* PCObserverString
;
90 class PeerConnectionObserver
;
91 typedef NS_ConvertUTF8toUTF16 PCObserverString
;
94 } // namespace mozilla
96 #if defined(__cplusplus) && __cplusplus >= 201103L
97 typedef struct Timecard Timecard
;
99 # include "common/time_profiling/timecard.h"
102 // To preserve blame, convert nsresult to ErrorResult with wrappers. These
103 // macros help declare wrappers w/function being wrapped when there are no
106 #define NS_IMETHODIMP_TO_ERRORRESULT(func, rv, ...) \
107 NS_IMETHODIMP func(__VA_ARGS__); \
108 void func(__VA_ARGS__, rv)
110 #define NS_IMETHODIMP_TO_ERRORRESULT_RETREF(resulttype, func, rv, ...) \
111 NS_IMETHODIMP func(__VA_ARGS__, resulttype** result); \
112 already_AddRefed<resulttype> func(__VA_ARGS__, rv)
116 using mozilla::DtlsIdentity
;
117 using mozilla::ErrorResult
;
118 using mozilla::PeerIdentity
;
119 using mozilla::dom::PeerConnectionObserver
;
120 using mozilla::dom::RTCConfiguration
;
121 using mozilla::dom::RTCIceServer
;
122 using mozilla::dom::RTCOfferOptions
;
124 class PeerConnectionWrapper
;
125 class RemoteSourceStreamInfo
;
128 class PCUuidGenerator
: public mozilla::JsepUuidGenerator
{
130 virtual bool Generate(std::string
* idp
) override
;
131 virtual mozilla::JsepUuidGenerator
* Clone() const override
{
132 return new PCUuidGenerator(*this);
136 nsCOMPtr
<nsIUUIDGenerator
> mGenerator
;
139 // This is a variation of Telemetry::AutoTimer that keeps a reference
140 // count and records the elapsed time when the count falls to zero. The
141 // elapsed time is recorded in seconds.
142 struct PeerConnectionAutoTimer
{
143 PeerConnectionAutoTimer()
144 : mRefCnt(0), mStart(TimeStamp::Now()), mUsedAV(false){};
145 void RegisterConnection();
146 void UnregisterConnection(bool aContainedAV
);
155 // Enter an API call and check that the state is OK,
156 // the PC isn't closed, etc.
157 #define PC_AUTO_ENTER_API_CALL(assert_ice_ready) \
159 /* do/while prevents res from conflicting with locals */ \
160 nsresult res = CheckApiState(assert_ice_ready); \
161 if (NS_FAILED(res)) return res; \
163 #define PC_AUTO_ENTER_API_CALL_VOID_RETURN(assert_ice_ready) \
165 /* do/while prevents res from conflicting with locals */ \
166 nsresult res = CheckApiState(assert_ice_ready); \
167 if (NS_FAILED(res)) return; \
169 #define PC_AUTO_ENTER_API_CALL_NO_CHECK() CheckThread()
171 class PeerConnectionImpl final
172 : public nsISupports
,
173 public nsWrapperCache
,
174 public mozilla::DataChannelConnection::DataConnectionListener
{
175 struct Internal
; // Avoid exposing c includes to bindings
178 explicit PeerConnectionImpl(
179 const mozilla::dom::GlobalObject
* aGlobal
= nullptr);
181 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
182 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(PeerConnectionImpl
)
184 struct RtpExtensionHeader
{
185 JsepMediaType mMediaType
;
186 SdpDirectionAttribute::Direction direction
;
187 std::string extensionname
;
190 JSObject
* WrapObject(JSContext
* aCx
,
191 JS::Handle
<JSObject
*> aGivenProto
) override
;
192 nsPIDOMWindowInner
* GetParentObject() const;
194 static already_AddRefed
<PeerConnectionImpl
> Constructor(
195 const mozilla::dom::GlobalObject
& aGlobal
);
197 // DataConnection observers
198 void NotifyDataChannel(already_AddRefed
<mozilla::DataChannel
> aChannel
)
199 // PeerConnectionImpl only inherits from mozilla::DataChannelConnection
203 void NotifyDataChannelOpen(DataChannel
*) override
;
205 void NotifyDataChannelClosed(DataChannel
*) override
;
207 void NotifySctpConnected() override
;
209 void NotifySctpClosed() override
;
211 const RefPtr
<MediaTransportHandler
> GetTransportHandler() const;
213 // Handle system to allow weak references to be passed through C code
214 virtual const std::string
& GetHandle();
216 // Name suitable for exposing to content
217 virtual const std::string
& GetName();
220 void IceConnectionStateChange(dom::RTCIceConnectionState state
);
221 void IceGatheringStateChange(dom::RTCIceGatheringState state
);
222 void OnCandidateFound(const std::string
& aTransportId
,
223 const CandidateInfo
& aCandidateInfo
);
224 void UpdateDefaultCandidate(const std::string
& defaultAddr
,
225 uint16_t defaultPort
,
226 const std::string
& defaultRtcpAddr
,
227 uint16_t defaultRtcpPort
,
228 const std::string
& transportId
);
230 static void ListenThread(void* aData
);
231 static void ConnectThread(void* aData
);
233 // Get the STS thread
234 nsISerialEventTarget
* GetSTSThread() {
235 PC_AUTO_ENTER_API_CALL_NO_CHECK();
239 nsresult
Initialize(PeerConnectionObserver
& aObserver
,
240 nsGlobalWindowInner
* aWindow
);
242 // Initialize PeerConnection from an RTCConfiguration object (JS entrypoint)
243 void Initialize(PeerConnectionObserver
& aObserver
,
244 nsGlobalWindowInner
& aWindow
, ErrorResult
& rv
);
246 void SetCertificate(mozilla::dom::RTCCertificate
& aCertificate
);
247 const RefPtr
<mozilla::dom::RTCCertificate
>& Certificate() const;
248 // This is a hack to support external linkage.
249 RefPtr
<DtlsIdentity
> Identity() const;
251 NS_IMETHODIMP_TO_ERRORRESULT(CreateOffer
, ErrorResult
& rv
,
252 const RTCOfferOptions
& aOptions
) {
253 rv
= CreateOffer(aOptions
);
256 NS_IMETHODIMP
CreateAnswer();
257 void CreateAnswer(ErrorResult
& rv
) { rv
= CreateAnswer(); }
259 NS_IMETHODIMP
CreateOffer(const mozilla::JsepOfferOptions
& aConstraints
);
261 NS_IMETHODIMP
SetLocalDescription(int32_t aAction
, const char* aSDP
);
263 void SetLocalDescription(int32_t aAction
, const nsAString
& aSDP
,
265 rv
= SetLocalDescription(aAction
, NS_ConvertUTF16toUTF8(aSDP
).get());
268 NS_IMETHODIMP
SetRemoteDescription(int32_t aAction
, const char* aSDP
);
270 void SetRemoteDescription(int32_t aAction
, const nsAString
& aSDP
,
272 rv
= SetRemoteDescription(aAction
, NS_ConvertUTF16toUTF8(aSDP
).get());
275 already_AddRefed
<dom::Promise
> GetStats(dom::MediaStreamTrack
* aSelector
);
277 void GetRemoteStreams(nsTArray
<RefPtr
<DOMMediaStream
>>& aStreamsOut
) const;
279 NS_IMETHODIMP
AddIceCandidate(const char* aCandidate
, const char* aMid
,
281 const dom::Nullable
<unsigned short>& aLevel
);
283 void AddIceCandidate(const nsAString
& aCandidate
, const nsAString
& aMid
,
284 const nsAString
& aUfrag
,
285 const dom::Nullable
<unsigned short>& aLevel
,
287 rv
= AddIceCandidate(NS_ConvertUTF16toUTF8(aCandidate
).get(),
288 NS_ConvertUTF16toUTF8(aMid
).get(),
289 NS_ConvertUTF16toUTF8(aUfrag
).get(), aLevel
);
292 void UpdateNetworkState(bool online
);
294 NS_IMETHODIMP
CloseStreams();
296 void CloseStreams(ErrorResult
& rv
) { rv
= CloseStreams(); }
298 already_AddRefed
<dom::RTCRtpTransceiver
> AddTransceiver(
299 const dom::RTCRtpTransceiverInit
& aInit
, const nsAString
& aKind
,
300 dom::MediaStreamTrack
* aSendTrack
, bool aAddTrackMagic
, ErrorResult
& aRv
);
302 bool CheckNegotiationNeeded();
303 bool CreatedSender(const dom::RTCRtpSender
& aSender
) const;
306 NS_IMETHODIMP_TO_ERRORRESULT(EnablePacketDump
, ErrorResult
& rv
,
307 unsigned long level
, dom::mozPacketDumpType type
,
309 rv
= EnablePacketDump(level
, type
, sending
);
313 NS_IMETHODIMP_TO_ERRORRESULT(DisablePacketDump
, ErrorResult
& rv
,
314 unsigned long level
, dom::mozPacketDumpType type
,
316 rv
= DisablePacketDump(level
, type
, sending
);
319 void GetPeerIdentity(nsAString
& peerIdentity
) {
321 peerIdentity
= mPeerIdentity
->ToString();
325 peerIdentity
.SetIsVoid(true);
328 const PeerIdentity
* GetPeerIdentity() const { return mPeerIdentity
; }
329 NS_IMETHODIMP_TO_ERRORRESULT(SetPeerIdentity
, ErrorResult
& rv
,
330 const nsAString
& peerIdentity
) {
331 rv
= SetPeerIdentity(peerIdentity
);
334 const std::string
& GetIdAsAscii() const { return mName
; }
336 void GetId(nsAString
& id
) { id
= NS_ConvertASCIItoUTF16(mName
.c_str()); }
338 void SetId(const nsAString
& id
) { mName
= NS_ConvertUTF16toUTF8(id
).get(); }
340 // this method checks to see if we've made a promise to protect media.
341 bool PrivacyRequested() const {
342 return mRequestedPrivacy
.valueOr(PrincipalPrivacy::NonPrivate
) ==
343 PrincipalPrivacy::Private
;
346 NS_IMETHODIMP
GetFingerprint(char** fingerprint
);
347 void GetFingerprint(nsAString
& fingerprint
) {
349 nsresult rv
= GetFingerprint(&tmp
);
350 NS_ENSURE_SUCCESS_VOID(rv
);
351 fingerprint
.AssignASCII(tmp
);
355 void GetCurrentLocalDescription(nsAString
& aSDP
) const;
356 void GetPendingLocalDescription(nsAString
& aSDP
) const;
358 void GetCurrentRemoteDescription(nsAString
& aSDP
) const;
359 void GetPendingRemoteDescription(nsAString
& aSDP
) const;
361 dom::Nullable
<bool> GetCurrentOfferer() const;
362 dom::Nullable
<bool> GetPendingOfferer() const;
364 NS_IMETHODIMP
SignalingState(mozilla::dom::RTCSignalingState
* aState
);
366 mozilla::dom::RTCSignalingState
SignalingState() {
367 mozilla::dom::RTCSignalingState state
;
368 SignalingState(&state
);
372 NS_IMETHODIMP
IceConnectionState(mozilla::dom::RTCIceConnectionState
* aState
);
374 mozilla::dom::RTCIceConnectionState
IceConnectionState() {
375 mozilla::dom::RTCIceConnectionState state
;
376 IceConnectionState(&state
);
380 NS_IMETHODIMP
IceGatheringState(mozilla::dom::RTCIceGatheringState
* aState
);
382 mozilla::dom::RTCIceGatheringState
IceGatheringState() {
383 return mIceGatheringState
;
386 NS_IMETHODIMP
ConnectionState(mozilla::dom::RTCPeerConnectionState
* aState
);
388 mozilla::dom::RTCPeerConnectionState
ConnectionState() {
389 mozilla::dom::RTCPeerConnectionState state
;
390 ConnectionState(&state
);
394 NS_IMETHODIMP
Close();
396 void Close(ErrorResult
& rv
) { rv
= Close(); }
398 // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
399 MOZ_CAN_RUN_SCRIPT_BOUNDARY
bool PluginCrash(uint32_t aPluginID
,
400 const nsAString
& aPluginName
);
402 NS_IMETHODIMP_TO_ERRORRESULT(SetConfiguration
, ErrorResult
& rv
,
403 const RTCConfiguration
& aConfiguration
) {
404 rv
= SetConfiguration(aConfiguration
);
407 dom::RTCSctpTransport
* GetSctp() const;
410 void RestartIceNoRenegotiationNeeded();
412 void RecordEndOfCallTelemetry();
414 nsresult
InitializeDataChannel();
416 NS_IMETHODIMP_TO_ERRORRESULT_RETREF(nsDOMDataChannel
, CreateDataChannel
,
417 ErrorResult
& rv
, const nsAString
& aLabel
,
418 const nsAString
& aProtocol
,
419 uint16_t aType
, bool outOfOrderAllowed
,
420 uint16_t aMaxTime
, uint16_t aMaxNum
,
421 bool aExternalNegotiated
,
424 // Base class for chained operations. Necessary right now because some
425 // operations come from JS (in the form of dom::ChainedOperation), and others
426 // come from c++ (dom::ChainedOperation is very unwieldy and arcane to build
427 // in c++). Once we stop using JSImpl, we should be able to simplify this.
428 class Operation
: public dom::PromiseNativeHandler
{
430 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
431 NS_DECL_CYCLE_COLLECTION_CLASS(Operation
)
432 Operation(PeerConnectionImpl
* aPc
, ErrorResult
& aError
);
434 void Call(ErrorResult
& aError
);
435 dom::Promise
* GetPromise() { return mPromise
; }
437 void ResolvedCallback(JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
,
438 ErrorResult
& aRv
) override
;
441 void RejectedCallback(JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
,
442 ErrorResult
& aRv
) override
;
446 virtual RefPtr
<dom::Promise
> CallImpl(ErrorResult
& aError
) = 0;
447 virtual ~Operation();
448 // This is the promise p from https://w3c.github.io/webrtc-pc/#dfn-chain
449 // This will be a content promise, since we return this to the caller of
451 RefPtr
<dom::Promise
> mPromise
;
452 RefPtr
<PeerConnectionImpl
> mPc
;
455 class JSOperation final
: public Operation
{
457 JSOperation(PeerConnectionImpl
* aPc
, dom::ChainedOperation
& aOp
,
458 ErrorResult
& aError
);
459 NS_DECL_ISUPPORTS_INHERITED
460 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(JSOperation
, Operation
)
464 RefPtr
<dom::Promise
> CallImpl(ErrorResult
& aError
) override
;
465 ~JSOperation() = default;
466 RefPtr
<dom::ChainedOperation
> mOperation
;
470 already_AddRefed
<dom::Promise
> Chain(dom::ChainedOperation
& aOperation
,
471 ErrorResult
& aError
);
473 already_AddRefed
<dom::Promise
> Chain(const RefPtr
<Operation
>& aOperation
,
474 ErrorResult
& aError
);
475 already_AddRefed
<dom::Promise
> MakePromise(ErrorResult
& aError
) const;
477 void UpdateNegotiationNeeded();
479 void GetTransceivers(
480 nsTArray
<RefPtr
<dom::RTCRtpTransceiver
>>& aTransceiversOut
) {
481 aTransceiversOut
= mTransceivers
.Clone();
484 // Gets the RTC Signaling State of the JSEP session
485 dom::RTCSignalingState
GetSignalingState() const;
487 already_AddRefed
<dom::Promise
> OnSetDescriptionSuccess(
488 dom::RTCSdpType aSdpType
, bool aRemote
, ErrorResult
& aError
);
490 void OnSetDescriptionError();
492 bool IsClosed() const;
494 // called when DTLS connects; we only need this once
495 nsresult
OnAlpnNegotiated(bool aPrivacyRequested
);
497 void OnDtlsStateChange(const std::string
& aTransportId
,
498 TransportLayer::State aState
);
499 dom::RTCPeerConnectionState
GetNewConnectionState() const;
500 // Returns whether we need to fire a state change event
501 bool UpdateConnectionState();
503 // initialize telemetry for when calls start
504 void StartCallTelem();
506 // Gets all codec stats for all transports, coalesced to transport level.
507 nsTArray
<dom::RTCCodecStats
> GetCodecStats(DOMHighResTimeStamp aNow
);
509 RefPtr
<dom::RTCStatsReportPromise
> GetStats(dom::MediaStreamTrack
* aSelector
,
510 bool aInternalStats
);
512 void CollectConduitTelemetryData();
514 void OnMediaError(const std::string
& aError
);
516 void DumpPacket_m(size_t level
, dom::mozPacketDumpType type
, bool sending
,
517 UniquePtr
<uint8_t[]>& packet
, size_t size
);
519 const dom::RTCStatsTimestampMaker
& GetTimestampMaker() const {
520 return mTimestampMaker
;
523 // Utility function, given a string pref and an URI, returns whether or not
524 // the URI occurs in the pref. Wildcards are supported (e.g. *.example.com)
525 // and multiple hostnames can be present, separated by commas.
526 static bool HostnameInPref(const char* aPrefList
, const nsCString
& aHostName
);
528 void StampTimecard(const char* aEvent
);
530 bool RelayOnly() const {
531 return mJsConfiguration
.mIceTransportPolicy
.WasPassed() &&
532 mJsConfiguration
.mIceTransportPolicy
.Value() ==
533 dom::RTCIceTransportPolicy::Relay
;
536 RefPtr
<PacketDumper
> GetPacketDumper() {
537 if (!mPacketDumper
) {
538 mPacketDumper
= new PacketDumper(mHandle
);
541 return mPacketDumper
;
544 nsString
GenerateUUID() const {
546 if (!mUuidGen
->Generate(&result
)) {
549 return NS_ConvertUTF8toUTF16(result
.c_str());
552 bool ShouldAllowOldSetParameters() const { return mAllowOldSetParameters
; }
554 nsCString
GetHostname() const { return mHostname
; }
555 nsCString
GetEffectiveTLDPlus1() const { return mEffectiveTLDPlus1
; }
557 void SendWarningToConsole(const nsCString
& aWarning
);
559 const UniquePtr
<dom::RTCStatsReportInternal
>& GetFinalStats() const {
563 void DisableLongTermStats() { mDisableLongTermStats
= true; }
565 bool LongTermStatsIsDisabled() const { return mDisableLongTermStats
; }
567 static void GetDefaultVideoCodecs(
568 std::vector
<UniquePtr
<JsepCodecDescription
>>& aSupportedCodecs
,
571 static void GetDefaultAudioCodecs(
572 std::vector
<UniquePtr
<JsepCodecDescription
>>& aSupportedCodecs
);
574 static void GetDefaultRtpExtensions(
575 std::vector
<RtpExtensionHeader
>& aRtpExtensions
);
577 static void GetCapabilities(const nsAString
& aKind
,
578 dom::Nullable
<dom::RTCRtpCapabilities
>& aResult
,
579 sdp::Direction aDirection
);
580 static void SetupPreferredCodecs(
581 std::vector
<UniquePtr
<JsepCodecDescription
>>& aPreferredCodecs
);
583 static void SetupPreferredRtpExtensions(
584 std::vector
<RtpExtensionHeader
>& aPreferredheaders
);
587 virtual ~PeerConnectionImpl();
588 PeerConnectionImpl(const PeerConnectionImpl
& rhs
);
589 PeerConnectionImpl
& operator=(PeerConnectionImpl
);
591 RefPtr
<dom::RTCStatsPromise
> GetDataChannelStats(
592 const RefPtr
<DataChannelConnection
>& aDataChannelConnection
,
593 const DOMHighResTimeStamp aTimestamp
);
594 nsresult
CalculateFingerprint(const std::string
& algorithm
,
595 std::vector
<uint8_t>* fingerprint
) const;
596 nsresult
ConfigureJsepSessionCodecs();
598 NS_IMETHODIMP
EnsureDataConnection(uint16_t aLocalPort
, uint16_t aNumstreams
,
599 uint32_t aMaxMessageSize
, bool aMMSSet
);
601 nsresult
CheckApiState(bool assert_ice_ready
) const;
602 void StoreFinalStats(UniquePtr
<dom::RTCStatsReportInternal
>&& report
);
603 void CheckThread() const { MOZ_ASSERT(NS_IsMainThread(), "Wrong thread"); }
605 // test-only: called from AddRIDExtension and AddRIDFilter
606 // for simulcast mochitests.
607 RefPtr
<MediaPipeline
> GetMediaPipelineForTrack(
608 dom::MediaStreamTrack
& aRecvTrack
);
610 void CandidateReady(const std::string
& candidate
,
611 const std::string
& transportId
, const std::string
& ufrag
);
612 void SendLocalIceCandidateToContent(uint16_t level
, const std::string
& mid
,
613 const std::string
& candidate
,
614 const std::string
& ufrag
);
616 nsresult
GetDatachannelParameters(uint32_t* channels
, uint16_t* localport
,
617 uint16_t* remoteport
,
618 uint32_t* maxmessagesize
, bool* mmsset
,
619 std::string
* transportId
,
622 nsresult
AddRtpTransceiverToJsepSession(JsepTransceiver
& transceiver
);
624 void RecordIceRestartStatistics(JsepSdpType type
);
626 void StoreConfigurationForAboutWebrtc(const RTCConfiguration
& aConfig
);
628 dom::Sequence
<dom::RTCSdpParsingErrorInternal
> GetLastSdpParsingErrors()
632 void RunNextOperation(ErrorResult
& aError
);
637 void DoSetDescriptionSuccessPostProcessing(dom::RTCSdpType aSdpType
,
639 const RefPtr
<dom::Promise
>& aP
);
641 // Timecard used to measure processing time. This should be the first class
642 // attribute so that we accurately measure the time required to instantiate
643 // any other attributes of this class.
646 // Configuration used to initialize the PeerConnection
647 dom::RTCConfigurationInternal mJsConfiguration
;
649 mozilla::dom::RTCSignalingState mSignalingState
;
652 mozilla::dom::RTCIceConnectionState mIceConnectionState
;
653 mozilla::dom::RTCIceGatheringState mIceGatheringState
;
655 mozilla::dom::RTCPeerConnectionState mConnectionState
;
657 RefPtr
<PeerConnectionObserver
> mPCObserver
;
659 nsCOMPtr
<nsPIDOMWindowInner
> mWindow
;
661 // The SDP sent in from JS
662 std::string mLocalRequestedSDP
;
663 std::string mRemoteRequestedSDP
;
664 // Only accessed from main
665 mozilla::dom::Sequence
<mozilla::dom::RTCSdpHistoryEntryInternal
> mSdpHistory
;
666 std::string mPendingLocalDescription
;
667 std::string mPendingRemoteDescription
;
668 std::string mCurrentLocalDescription
;
669 std::string mCurrentRemoteDescription
;
670 Maybe
<bool> mPendingOfferer
;
671 Maybe
<bool> mCurrentOfferer
;
674 std::string mFingerprint
;
675 std::string mRemoteFingerprint
;
677 // identity-related fields
678 // The entity on the other end of the peer-to-peer connection;
679 // void if they are not yet identified, and no identity setting has been set
680 RefPtr
<PeerIdentity
> mPeerIdentity
;
681 // The certificate we are using.
682 RefPtr
<mozilla::dom::RTCCertificate
> mCertificate
;
683 // Whether an app should be prevented from accessing media produced by the PC
684 // If this is true, then media will not be sent until mPeerIdentity matches
685 // local streams PeerIdentity; and remote streams are protected from content
687 // This can be false if mPeerIdentity is set, in the case where identity is
688 // provided, but the media is not protected from the app on either side
689 Maybe
<PrincipalPrivacy
> mRequestedPrivacy
;
691 // A handle to refer to this PC with
694 // A name for this PC that we are willing to expose to content.
697 nsCString mEffectiveTLDPlus1
;
699 // The target to run stuff on
700 nsCOMPtr
<nsISerialEventTarget
> mSTSThread
;
702 // DataConnection that's used to get all the DataChannels
703 RefPtr
<mozilla::DataChannelConnection
> mDataConnection
;
704 unsigned int mDataChannelsOpened
= 0;
705 unsigned int mDataChannelsClosed
= 0;
708 RefPtr
<MediaTransportHandler
> mTransportHandler
;
710 // The JSEP negotiation session.
711 mozilla::UniquePtr
<PCUuidGenerator
> mUuidGen
;
712 mozilla::UniquePtr
<mozilla::JsepSession
> mJsepSession
;
713 // There are lots of error cases where we want to abandon an sRD/sLD _after_
714 // it has already been applied to the JSEP engine, and revert back to the
715 // previous state. We also want to ensure that the various modifications
716 // to the JSEP engine are not exposed to JS until the sRD/sLD completes,
717 // which is why we have a new "uncommitted" JSEP engine.
718 mozilla::UniquePtr
<mozilla::JsepSession
> mUncommittedJsepSession
;
719 unsigned long mIceRestartCount
;
720 unsigned long mIceRollbackCount
;
722 // The following are used for Telemetry:
723 bool mCallTelemStarted
= false;
724 bool mCallTelemEnded
= false;
726 // We _could_ make mFinalStatsQuery be an RTCStatsReportPromise, but that
727 // would require RTCStatsReportPromise to no longer be exclusive, which is
728 // a bit of a hassle, and not very performant.
729 RefPtr
<GenericNonExclusivePromise
> mFinalStatsQuery
;
730 UniquePtr
<dom::RTCStatsReportInternal
> mFinalStats
;
731 bool mDisableLongTermStats
= false;
733 // Start time of ICE.
734 mozilla::TimeStamp mIceStartTime
;
735 // Hold PeerConnectionAutoTimer instances for each window.
736 static std::map
<uint64_t, PeerConnectionAutoTimer
> sCallDurationTimers
;
738 bool mHaveConfiguredCodecs
;
744 // Whether this PeerConnection is being counted as active by mWindow
745 bool mActiveOnWindow
;
747 // storage for Telemetry data
748 uint16_t mMaxReceiving
[SdpMediaSection::kMediaTypes
];
749 uint16_t mMaxSending
[SdpMediaSection::kMediaTypes
];
751 // used to store the raw trickle candidate string for display
752 // on the about:webrtc raw candidates table.
753 std::vector
<std::string
> mRawTrickledCandidates
;
755 dom::RTCStatsTimestampMaker mTimestampMaker
;
757 RefPtr
<RTCStatsIdGenerator
> mIdGenerator
;
758 // Ordinarily, I would use a std::map here, but this used to be a JS Map
759 // which iterates in insertion order, and I want to avoid changing this.
760 nsTArray
<RefPtr
<DOMMediaStream
>> mReceiveStreams
;
762 DOMMediaStream
* GetReceiveStream(const std::string
& aId
) const;
763 DOMMediaStream
* CreateReceiveStream(const std::string
& aId
);
765 void InitLocalAddrs(); // for stun local address IPC request
766 bool ShouldForceProxy() const;
767 std::unique_ptr
<NrSocketProxyConfig
> GetProxyConfig() const;
769 class StunAddrsHandler
: public net::StunAddrsListener
{
771 explicit StunAddrsHandler(PeerConnectionImpl
* aPc
)
772 : mPcHandle(aPc
->GetHandle()) {}
774 void OnMDNSQueryComplete(const nsCString
& hostname
,
775 const Maybe
<nsCString
>& address
) override
;
777 void OnStunAddrsAvailable(
778 const mozilla::net::NrIceStunAddrArray
& addrs
) override
;
781 // This class is not cycle-collected, so we must avoid grabbing a strong
783 const std::string mPcHandle
;
784 virtual ~StunAddrsHandler() {}
787 // Manage ICE transports.
788 void UpdateTransport(const JsepTransceiver
& aTransceiver
, bool aForceIceTcp
);
790 void GatherIfReady();
791 void FlushIceCtxOperationQueueIfReady();
792 void PerformOrEnqueueIceCtxOperation(nsIRunnable
* runnable
);
793 nsresult
SetTargetForDefaultLocalAddressLookup();
794 void EnsureIceGathering(bool aDefaultRouteOnly
, bool aObfuscateHostAddresses
);
796 bool GetPrefDefaultAddressOnly() const;
797 bool GetPrefObfuscateHostAddresses() const;
799 bool IsIceCtxReady() const {
800 return mLocalAddrsRequestState
== STUN_ADDR_REQUEST_COMPLETE
;
803 // Ensure ICE transports exist that we might need when offer/answer concludes
804 void EnsureTransports(const JsepSession
& aSession
);
806 void UpdateRTCDtlsTransports(bool aMarkAsStable
);
807 void RollbackRTCDtlsTransports();
808 void RemoveRTCDtlsTransportsExcept(
809 const std::set
<std::string
>& aTransportIds
);
811 // Activate ICE transports at the conclusion of offer/answer,
812 // or when rollback occurs.
813 nsresult
UpdateTransports(const JsepSession
& aSession
,
814 const bool forceIceTcp
);
816 void ResetStunAddrsForIceRestart() { mStunAddrs
.Clear(); }
819 void StartIceChecks(const JsepSession
& session
);
821 // Process a trickle ICE candidate.
822 void AddIceCandidate(const std::string
& candidate
,
823 const std::string
& aTransportId
,
824 const std::string
& aUFrag
);
826 // Handle complete media pipelines.
827 // This updates codec parameters, starts/stops send/receive, and other
828 // stuff that doesn't necessarily require negotiation. This can be called at
829 // any time, not just when an offer/answer exchange completes.
830 nsresult
UpdateMediaPipelines();
832 already_AddRefed
<dom::RTCRtpTransceiver
> CreateTransceiver(
833 const std::string
& aId
, bool aIsVideo
,
834 const dom::RTCRtpTransceiverInit
& aInit
,
835 dom::MediaStreamTrack
* aSendTrack
, bool aAddTrackMagic
, ErrorResult
& aRv
);
837 std::string
GetTransportIdMatchingSendTrack(
838 const dom::MediaStreamTrack
& aTrack
) const;
840 // this determines if any track is peerIdentity constrained
841 bool AnyLocalTrackHasPeerIdentity() const;
843 bool AnyCodecHasPluginID(uint64_t aPluginID
);
845 already_AddRefed
<nsIHttpChannelInternal
> GetChannel() const;
849 bool HasPendingSetParameters() const;
850 void InvalidateLastReturnedParameters();
852 RefPtr
<WebrtcCallWrapper
> mCall
;
854 // See Bug 1642419, this can be removed when all sites are working with RTX.
855 bool mRtxIsAllowed
= true;
857 nsTArray
<RefPtr
<Operation
>> mOperations
;
858 bool mChainingOperation
= false;
859 bool mUpdateNegotiationNeededFlagOnEmptyChain
= false;
860 bool mNegotiationNeeded
= false;
861 std::set
<std::pair
<std::string
, std::string
>> mLocalIceCredentialsToReplace
;
863 nsTArray
<RefPtr
<dom::RTCRtpTransceiver
>> mTransceivers
;
864 std::map
<std::string
, RefPtr
<dom::RTCDtlsTransport
>>
865 mTransportIdToRTCDtlsTransport
;
866 RefPtr
<dom::RTCSctpTransport
> mSctpTransport
;
868 // Used whenever we need to dispatch a runnable to STS to tweak something
869 // on our ICE ctx, but are not ready to do so at the moment (eg; we are
870 // waiting to get a callback with our http proxy config before we start
871 // gathering or start checking)
872 std::vector
<nsCOMPtr
<nsIRunnable
>> mQueuedIceCtxOperations
;
874 // Set if prefs dictate that we should force the use of a web proxy.
875 bool mForceProxy
= false;
877 // Used to cancel incoming stun addrs response
878 RefPtr
<net::StunAddrsRequestChild
> mStunAddrsRequest
;
880 enum StunAddrRequestState
{
881 STUN_ADDR_REQUEST_NONE
,
882 STUN_ADDR_REQUEST_PENDING
,
883 STUN_ADDR_REQUEST_COMPLETE
885 // Used to track the state of the stun addr IPC request
886 StunAddrRequestState mLocalAddrsRequestState
= STUN_ADDR_REQUEST_NONE
;
888 // Used to store the result of the stun addr IPC request
889 nsTArray
<NrIceStunAddr
> mStunAddrs
;
891 // Used to ensure the target for default local address lookup is only set
893 bool mTargetForDefaultLocalAddressLookupIsSet
= false;
895 // Keep track of local hostnames to register. Registration is deferred
896 // until StartIceChecks has run. Accessed on main thread only.
897 std::map
<std::string
, std::string
> mMDNSHostnamesToRegister
;
898 bool mCanRegisterMDNSHostnamesDirectly
= false;
900 // Used to store the mDNS hostnames that we have registered
901 std::set
<std::string
> mRegisteredMDNSHostnames
;
903 // web-compat stopgap
904 bool mAllowOldSetParameters
= false;
906 // Used to store the mDNS hostnames that we have queried
907 struct PendingIceCandidate
{
908 std::vector
<std::string
> mTokenizedCandidate
;
909 std::string mTransportId
;
912 std::map
<std::string
, std::list
<PendingIceCandidate
>> mQueriedMDNSHostnames
;
914 // Connecting PCImpl to sigslot is not safe, because sigslot takes strong
915 // references without any reference counting, and JS holds refcounted strong
916 // references to PCImpl (meaning JS can cause PCImpl to be destroyed). This
917 // is not ref-counted (since sigslot holds onto non-refcounted strong refs)
918 // Must be destroyed on STS. Holds a weak reference to PCImpl.
919 class SignalHandler
: public sigslot::has_slots
<> {
921 SignalHandler(PeerConnectionImpl
* aPc
, MediaTransportHandler
* aSource
);
922 virtual ~SignalHandler();
924 void ConnectSignals();
927 void IceGatheringStateChange_s(dom::RTCIceGatheringState aState
);
928 void IceConnectionStateChange_s(dom::RTCIceConnectionState aState
);
929 void OnCandidateFound_s(const std::string
& aTransportId
,
930 const CandidateInfo
& aCandidateInfo
);
931 void AlpnNegotiated_s(const std::string
& aAlpn
, bool aPrivacyRequested
);
932 void ConnectionStateChange_s(const std::string
& aTransportId
,
933 TransportLayer::State aState
);
934 void OnPacketReceived_s(const std::string
& aTransportId
,
935 const MediaPacket
& aPacket
);
937 MediaEventSourceExc
<MediaPacket
>& RtcpReceiveEvent() {
938 return mRtcpReceiveEvent
;
942 const std::string mHandle
;
943 RefPtr
<MediaTransportHandler
> mSource
;
944 RefPtr
<nsISerialEventTarget
> mSTSThread
;
945 RefPtr
<PacketDumper
> mPacketDumper
;
946 MediaEventProducerExc
<MediaPacket
> mRtcpReceiveEvent
;
949 mozilla::UniquePtr
<SignalHandler
> mSignalHandler
;
950 MediaEventListener mRtcpReceiveListener
;
952 // Make absolutely sure our refcount does not go to 0 before Close() is called
953 // This is because Close does a stats query, which needs the
954 // PeerConnectionImpl to stick around until the query is done.
955 RefPtr
<PeerConnectionImpl
> mKungFuDeathGrip
;
956 RefPtr
<PacketDumper
> mPacketDumper
;
959 // these are temporary until the DataChannel Listen/Connect API is removed
960 unsigned short listenPort
;
961 unsigned short connectPort
;
962 char* connectStr
; // XXX ownership/free
965 // This is what is returned when you acquire on a handle
966 class PeerConnectionWrapper
{
968 explicit PeerConnectionWrapper(const std::string
& handle
);
970 PeerConnectionImpl
* impl() { return impl_
; }
973 RefPtr
<PeerConnectionImpl
> impl_
;
976 } // namespace mozilla
978 #undef NS_IMETHODIMP_TO_ERRORRESULT
979 #undef NS_IMETHODIMP_TO_ERRORRESULT_RETREF
980 #endif // _PEER_CONNECTION_IMPL_H_