Backed out changeset f0458ed00feb (bug 1854490) for causing build bustages on dom...
[gecko.git] / dom / media / webrtc / jsapi / PeerConnectionImpl.h
blobf46c433fd216fc1399ea9af8bc4bf6fb70934fea
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_
8 #include <string>
9 #include <vector>
10 #include <map>
11 #include <cmath>
13 #include "prlock.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
23 #ifdef GetLastError
24 # undef GetLastError
25 #endif
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"
57 namespace test {
58 #ifdef USE_FAKE_PCOBSERVER
59 class AFakePCObserver;
60 #endif
61 } // namespace test
63 class nsDOMDataChannel;
64 class nsIPrincipal;
66 namespace mozilla {
67 struct CandidateInfo;
68 class DataChannel;
69 class DtlsIdentity;
70 class MediaPipeline;
71 class MediaPipelineReceive;
72 class MediaPipelineTransmit;
73 enum class PrincipalPrivacy : uint8_t;
74 class SharedWebrtcState;
76 namespace dom {
77 class RTCCertificate;
78 struct RTCConfiguration;
79 struct RTCRtpSourceEntry;
80 struct RTCIceServer;
81 struct RTCOfferOptions;
82 struct RTCRtpParameters;
83 class RTCRtpSender;
84 class MediaStreamTrack;
86 #ifdef USE_FAKE_PCOBSERVER
87 typedef test::AFakePCObserver PeerConnectionObserver;
88 typedef const char* PCObserverString;
89 #else
90 class PeerConnectionObserver;
91 typedef NS_ConvertUTF8toUTF16 PCObserverString;
92 #endif
93 } // namespace dom
94 } // namespace mozilla
96 #if defined(__cplusplus) && __cplusplus >= 201103L
97 typedef struct Timecard Timecard;
98 #else
99 # include "common/time_profiling/timecard.h"
100 #endif
102 // To preserve blame, convert nsresult to ErrorResult with wrappers. These
103 // macros help declare wrappers w/function being wrapped when there are no
104 // differences.
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)
114 namespace mozilla {
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;
127 // Uuid Generator
128 class PCUuidGenerator : public mozilla::JsepUuidGenerator {
129 public:
130 virtual bool Generate(std::string* idp) override;
131 virtual mozilla::JsepUuidGenerator* Clone() const override {
132 return new PCUuidGenerator(*this);
135 private:
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);
147 bool IsStopped();
149 private:
150 int64_t mRefCnt;
151 TimeStamp mStart;
152 bool mUsedAV;
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) \
158 do { \
159 /* do/while prevents res from conflicting with locals */ \
160 nsresult res = CheckApiState(assert_ice_ready); \
161 if (NS_FAILED(res)) return res; \
162 } while (0)
163 #define PC_AUTO_ENTER_API_CALL_VOID_RETURN(assert_ice_ready) \
164 do { \
165 /* do/while prevents res from conflicting with locals */ \
166 nsresult res = CheckApiState(assert_ice_ready); \
167 if (NS_FAILED(res)) return; \
168 } while (0)
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
177 public:
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
200 // inside libxul.
201 override;
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();
219 // ICE events
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();
236 return mSTSThread;
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,
264 ErrorResult& rv) {
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,
271 ErrorResult& rv) {
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,
280 const char* aUfrag,
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,
286 ErrorResult& rv) {
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;
305 // test-only
306 NS_IMETHODIMP_TO_ERRORRESULT(EnablePacketDump, ErrorResult& rv,
307 unsigned long level, dom::mozPacketDumpType type,
308 bool sending) {
309 rv = EnablePacketDump(level, type, sending);
312 // test-only
313 NS_IMETHODIMP_TO_ERRORRESULT(DisablePacketDump, ErrorResult& rv,
314 unsigned long level, dom::mozPacketDumpType type,
315 bool sending) {
316 rv = DisablePacketDump(level, type, sending);
319 void GetPeerIdentity(nsAString& peerIdentity) {
320 if (mPeerIdentity) {
321 peerIdentity = mPeerIdentity->ToString();
322 return;
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) {
348 char* tmp;
349 nsresult rv = GetFingerprint(&tmp);
350 NS_ENSURE_SUCCESS_VOID(rv);
351 fingerprint.AssignASCII(tmp);
352 delete[] 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);
369 return state;
372 NS_IMETHODIMP IceConnectionState(mozilla::dom::RTCIceConnectionState* aState);
374 mozilla::dom::RTCIceConnectionState IceConnectionState() {
375 mozilla::dom::RTCIceConnectionState state;
376 IceConnectionState(&state);
377 return 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);
391 return 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;
409 void RestartIce();
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,
422 uint16_t aStream);
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 {
429 public:
430 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
431 NS_DECL_CYCLE_COLLECTION_CLASS(Operation)
432 Operation(PeerConnectionImpl* aPc, ErrorResult& aError);
433 MOZ_CAN_RUN_SCRIPT
434 void Call(ErrorResult& aError);
435 dom::Promise* GetPromise() { return mPromise; }
436 MOZ_CAN_RUN_SCRIPT
437 void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
438 ErrorResult& aRv) override;
440 MOZ_CAN_RUN_SCRIPT
441 void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
442 ErrorResult& aRv) override;
444 protected:
445 MOZ_CAN_RUN_SCRIPT
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
450 // Chain.
451 RefPtr<dom::Promise> mPromise;
452 RefPtr<PeerConnectionImpl> mPc;
455 class JSOperation final : public Operation {
456 public:
457 JSOperation(PeerConnectionImpl* aPc, dom::ChainedOperation& aOp,
458 ErrorResult& aError);
459 NS_DECL_ISUPPORTS_INHERITED
460 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(JSOperation, Operation)
462 private:
463 MOZ_CAN_RUN_SCRIPT
464 RefPtr<dom::Promise> CallImpl(ErrorResult& aError) override;
465 ~JSOperation() = default;
466 RefPtr<dom::ChainedOperation> mOperation;
469 MOZ_CAN_RUN_SCRIPT
470 already_AddRefed<dom::Promise> Chain(dom::ChainedOperation& aOperation,
471 ErrorResult& aError);
472 MOZ_CAN_RUN_SCRIPT
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 {
545 std::string result;
546 if (!mUuidGen->Generate(&result)) {
547 MOZ_CRASH();
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 {
560 return mFinalStats;
563 void DisableLongTermStats() { mDisableLongTermStats = true; }
565 bool LongTermStatsIsDisabled() const { return mDisableLongTermStats; }
567 static void GetDefaultVideoCodecs(
568 std::vector<UniquePtr<JsepCodecDescription>>& aSupportedCodecs,
569 bool aUseRtx);
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);
586 private:
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,
620 bool* client) const;
622 nsresult AddRtpTransceiverToJsepSession(JsepTransceiver& transceiver);
624 void RecordIceRestartStatistics(JsepSdpType type);
626 void StoreConfigurationForAboutWebrtc(const RTCConfiguration& aConfig);
628 dom::Sequence<dom::RTCSdpParsingErrorInternal> GetLastSdpParsingErrors()
629 const;
631 MOZ_CAN_RUN_SCRIPT
632 void RunNextOperation(ErrorResult& aError);
634 void SyncToJsep();
635 void SyncFromJsep();
637 void DoSetDescriptionSuccessPostProcessing(dom::RTCSdpType aSdpType,
638 bool aRemote,
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.
644 Timecard* mTimeCard;
646 // Configuration used to initialize the PeerConnection
647 dom::RTCConfigurationInternal mJsConfiguration;
649 mozilla::dom::RTCSignalingState mSignalingState;
651 // ICE State
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;
673 // DTLS fingerprint
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
692 std::string mHandle;
694 // A name for this PC that we are willing to expose to content.
695 std::string mName;
696 nsCString mHostname;
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;
707 bool mForceIceTcp;
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;
740 bool mTrickle;
742 bool mPrivateWindow;
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 {
770 public:
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;
780 private:
781 // This class is not cycle-collected, so we must avoid grabbing a strong
782 // reference.
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(); }
818 // Start ICE checks.
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;
847 void BreakCycles();
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
892 // once.
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;
910 std::string mUfrag;
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<> {
920 public:
921 SignalHandler(PeerConnectionImpl* aPc, MediaTransportHandler* aSource);
922 virtual ~SignalHandler();
924 void ConnectSignals();
926 // ICE events
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;
941 private:
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;
958 public:
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 {
967 public:
968 explicit PeerConnectionWrapper(const std::string& handle);
970 PeerConnectionImpl* impl() { return impl_; }
972 private:
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_