Line data Source code
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/. */
4 :
5 : #ifndef _PEER_CONNECTION_IMPL_H_
6 : #define _PEER_CONNECTION_IMPL_H_
7 :
8 : #include <deque>
9 : #include <string>
10 : #include <vector>
11 : #include <map>
12 : #include <cmath>
13 :
14 : #include "prlock.h"
15 : #include "mozilla/RefPtr.h"
16 : #include "nsWeakPtr.h"
17 : #include "nsAutoPtr.h"
18 : #include "nsIWeakReferenceUtils.h" // for the definition of nsWeakPtr
19 : #include "IPeerConnection.h"
20 : #include "sigslot.h"
21 : #include "nricectx.h"
22 : #include "nricemediastream.h"
23 : #include "nsComponentManagerUtils.h"
24 : #include "nsPIDOMWindow.h"
25 : #include "nsIUUIDGenerator.h"
26 : #include "nsIThread.h"
27 :
28 : #include "signaling/src/jsep/JsepSession.h"
29 : #include "signaling/src/jsep/JsepSessionImpl.h"
30 : #include "signaling/src/sdp/SdpMediaSection.h"
31 :
32 : #include "mozilla/ErrorResult.h"
33 : #include "mozilla/dom/PeerConnectionImplEnumsBinding.h"
34 : #include "PrincipalChangeObserver.h"
35 : #include "StreamTracks.h"
36 :
37 : #include "mozilla/TimeStamp.h"
38 : #include "mozilla/net/DataChannel.h"
39 : #include "VideoUtils.h"
40 : #include "VideoSegment.h"
41 : #include "mozilla/dom/RTCStatsReportBinding.h"
42 : #include "nsIPrincipal.h"
43 : #include "mozilla/PeerIdentity.h"
44 :
45 : namespace test {
46 : #ifdef USE_FAKE_PCOBSERVER
47 : class AFakePCObserver;
48 : #endif
49 : }
50 :
51 : class nsGlobalWindow;
52 : class nsDOMDataChannel;
53 :
54 : namespace mozilla {
55 : class DataChannel;
56 : class DtlsIdentity;
57 : class NrIceCtx;
58 : class NrIceMediaStream;
59 : class NrIceStunServer;
60 : class NrIceTurnServer;
61 : class MediaPipeline;
62 :
63 : class DOMMediaStream;
64 :
65 : namespace dom {
66 : class RTCCertificate;
67 : struct RTCConfiguration;
68 : class RTCDTMFSender;
69 : struct RTCIceServer;
70 : struct RTCOfferOptions;
71 : struct RTCRtpParameters;
72 : class RTCRtpSender;
73 : class MediaStreamTrack;
74 :
75 : #ifdef USE_FAKE_PCOBSERVER
76 : typedef test::AFakePCObserver PeerConnectionObserver;
77 : typedef const char *PCObserverString;
78 : #else
79 : class PeerConnectionObserver;
80 : typedef NS_ConvertUTF8toUTF16 PCObserverString;
81 : #endif
82 : }
83 : }
84 :
85 : #if defined(__cplusplus) && __cplusplus >= 201103L
86 : typedef struct Timecard Timecard;
87 : #else
88 : #include "timecard.h"
89 : #endif
90 :
91 : // To preserve blame, convert nsresult to ErrorResult with wrappers. These macros
92 : // help declare wrappers w/function being wrapped when there are no differences.
93 :
94 : #define NS_IMETHODIMP_TO_ERRORRESULT(func, rv, ...) \
95 : NS_IMETHODIMP func(__VA_ARGS__); \
96 : void func (__VA_ARGS__, rv)
97 :
98 : #define NS_IMETHODIMP_TO_ERRORRESULT_RETREF(resulttype, func, rv, ...) \
99 : NS_IMETHODIMP func(__VA_ARGS__, resulttype **result); \
100 : already_AddRefed<resulttype> func (__VA_ARGS__, rv)
101 :
102 : struct MediaStreamTable;
103 :
104 : namespace mozilla {
105 :
106 : using mozilla::dom::PeerConnectionObserver;
107 : using mozilla::dom::RTCConfiguration;
108 : using mozilla::dom::RTCIceServer;
109 : using mozilla::dom::RTCOfferOptions;
110 : using mozilla::DOMMediaStream;
111 : using mozilla::NrIceCtx;
112 : using mozilla::NrIceMediaStream;
113 : using mozilla::DtlsIdentity;
114 : using mozilla::ErrorResult;
115 : using mozilla::NrIceStunServer;
116 : using mozilla::NrIceTurnServer;
117 : using mozilla::PeerIdentity;
118 :
119 : class PeerConnectionWrapper;
120 : class PeerConnectionMedia;
121 : class RemoteSourceStreamInfo;
122 :
123 : // Uuid Generator
124 0 : class PCUuidGenerator : public mozilla::JsepUuidGenerator {
125 : public:
126 : virtual bool Generate(std::string* idp) override;
127 :
128 : private:
129 : nsCOMPtr<nsIUUIDGenerator> mGenerator;
130 : };
131 :
132 0 : class PeerConnectionConfiguration
133 : {
134 : public:
135 0 : PeerConnectionConfiguration()
136 0 : : mBundlePolicy(kBundleBalanced),
137 0 : mIceTransportPolicy(NrIceCtx::ICE_POLICY_ALL) {}
138 :
139 0 : bool addStunServer(const std::string& addr, uint16_t port,
140 : const char* transport)
141 : {
142 0 : UniquePtr<NrIceStunServer> server(NrIceStunServer::Create(addr, port, transport));
143 0 : if (!server) {
144 0 : return false;
145 : }
146 0 : addStunServer(*server);
147 0 : return true;
148 : }
149 0 : bool addTurnServer(const std::string& addr, uint16_t port,
150 : const std::string& username,
151 : const std::string& pwd,
152 : const char* transport)
153 : {
154 : // TODO(ekr@rtfm.com): Need support for SASLprep for
155 : // username and password. Bug # ???
156 0 : std::vector<unsigned char> password(pwd.begin(), pwd.end());
157 :
158 : UniquePtr<NrIceTurnServer> server(NrIceTurnServer::Create(addr, port, username, password,
159 0 : transport));
160 0 : if (!server) {
161 0 : return false;
162 : }
163 0 : addTurnServer(*server);
164 0 : return true;
165 : }
166 0 : void addStunServer(const NrIceStunServer& server) { mStunServers.push_back (server); }
167 0 : void addTurnServer(const NrIceTurnServer& server) { mTurnServers.push_back (server); }
168 0 : const std::vector<NrIceStunServer>& getStunServers() const { return mStunServers; }
169 0 : const std::vector<NrIceTurnServer>& getTurnServers() const { return mTurnServers; }
170 0 : void setBundlePolicy(JsepBundlePolicy policy) { mBundlePolicy = policy;}
171 0 : JsepBundlePolicy getBundlePolicy() const { return mBundlePolicy; }
172 0 : void setIceTransportPolicy(NrIceCtx::Policy policy) { mIceTransportPolicy = policy;}
173 0 : NrIceCtx::Policy getIceTransportPolicy() const { return mIceTransportPolicy; }
174 :
175 : nsresult Init(const RTCConfiguration& aSrc);
176 : nsresult AddIceServer(const RTCIceServer& aServer);
177 :
178 : private:
179 : std::vector<NrIceStunServer> mStunServers;
180 : std::vector<NrIceTurnServer> mTurnServers;
181 : JsepBundlePolicy mBundlePolicy;
182 : NrIceCtx::Policy mIceTransportPolicy;
183 : };
184 :
185 : // Not an inner class so we can forward declare.
186 : class RTCStatsQuery {
187 : public:
188 : explicit RTCStatsQuery(bool internalStats);
189 : ~RTCStatsQuery();
190 :
191 : nsAutoPtr<mozilla::dom::RTCStatsReportInternal> report;
192 : std::string error;
193 : // A timestamp to help with telemetry.
194 : mozilla::TimeStamp iceStartTime;
195 : // Just for convenience, maybe integrate into the report later
196 : bool failed;
197 :
198 : private:
199 : friend class PeerConnectionImpl;
200 : std::string pcName;
201 : bool internalStats;
202 : nsTArray<RefPtr<mozilla::MediaPipeline>> pipelines;
203 : RefPtr<NrIceCtx> iceCtx;
204 : bool grabAllLevels;
205 : DOMHighResTimeStamp now;
206 : };
207 :
208 : // Enter an API call and check that the state is OK,
209 : // the PC isn't closed, etc.
210 : #define PC_AUTO_ENTER_API_CALL(assert_ice_ready) \
211 : do { \
212 : /* do/while prevents res from conflicting with locals */ \
213 : nsresult res = CheckApiState(assert_ice_ready); \
214 : if (NS_FAILED(res)) return res; \
215 : } while(0)
216 : #define PC_AUTO_ENTER_API_CALL_VOID_RETURN(assert_ice_ready) \
217 : do { \
218 : /* do/while prevents res from conflicting with locals */ \
219 : nsresult res = CheckApiState(assert_ice_ready); \
220 : if (NS_FAILED(res)) return; \
221 : } while(0)
222 : #define PC_AUTO_ENTER_API_CALL_NO_CHECK() CheckThread()
223 :
224 : class PeerConnectionImpl final : public nsISupports,
225 : public mozilla::DataChannelConnection::DataConnectionListener,
226 : public dom::PrincipalChangeObserver<dom::MediaStreamTrack>,
227 : public sigslot::has_slots<>
228 : {
229 : struct Internal; // Avoid exposing c includes to bindings
230 :
231 : public:
232 : explicit PeerConnectionImpl(const mozilla::dom::GlobalObject* aGlobal = nullptr);
233 :
234 : enum Error {
235 : kNoError = 0,
236 : kInvalidCandidate = 2,
237 : kInvalidMediastreamTrack = 3,
238 : kInvalidState = 4,
239 : kInvalidSessionDescription = 5,
240 : kIncompatibleSessionDescription = 6,
241 : kIncompatibleMediaStreamTrack = 8,
242 : kInternalError = 9
243 : };
244 :
245 : NS_DECL_THREADSAFE_ISUPPORTS
246 :
247 : bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
248 :
249 : static already_AddRefed<PeerConnectionImpl>
250 : Constructor(const mozilla::dom::GlobalObject& aGlobal, ErrorResult& rv);
251 : static PeerConnectionImpl* CreatePeerConnection();
252 : already_AddRefed<DOMMediaStream> MakeMediaStream();
253 :
254 : nsresult CreateRemoteSourceStreamInfo(RefPtr<RemoteSourceStreamInfo>* aInfo,
255 : const std::string& aId);
256 :
257 : // DataConnection observers
258 : void NotifyDataChannel(already_AddRefed<mozilla::DataChannel> aChannel)
259 : // PeerConnectionImpl only inherits from mozilla::DataChannelConnection
260 : // inside libxul.
261 : override
262 : ;
263 :
264 : // Get the media object
265 0 : const RefPtr<PeerConnectionMedia>& media() const {
266 0 : PC_AUTO_ENTER_API_CALL_NO_CHECK();
267 0 : return mMedia;
268 : }
269 :
270 : // Configure the ability to use localhost.
271 : void SetAllowIceLoopback(bool val) { mAllowIceLoopback = val; }
272 0 : bool GetAllowIceLoopback() const { return mAllowIceLoopback; }
273 :
274 : // Configure the ability to use IPV6 link-local addresses.
275 : void SetAllowIceLinkLocal(bool val) { mAllowIceLinkLocal = val; }
276 0 : bool GetAllowIceLinkLocal() const { return mAllowIceLinkLocal; }
277 :
278 : // Handle system to allow weak references to be passed through C code
279 : virtual const std::string& GetHandle();
280 :
281 : // Name suitable for exposing to content
282 : virtual const std::string& GetName();
283 :
284 : // ICE events
285 : void IceConnectionStateChange(NrIceCtx* ctx,
286 : NrIceCtx::ConnectionState state);
287 : void IceGatheringStateChange(NrIceCtx* ctx,
288 : NrIceCtx::GatheringState state);
289 : void UpdateDefaultCandidate(const std::string& defaultAddr,
290 : uint16_t defaultPort,
291 : const std::string& defaultRtcpAddr,
292 : uint16_t defaultRtcpPort,
293 : uint16_t level);
294 : void EndOfLocalCandidates(uint16_t level);
295 : void IceStreamReady(NrIceMediaStream *aStream);
296 :
297 : static void ListenThread(void *aData);
298 : static void ConnectThread(void *aData);
299 :
300 : // Get the main thread
301 0 : nsCOMPtr<nsIThread> GetMainThread() {
302 0 : PC_AUTO_ENTER_API_CALL_NO_CHECK();
303 0 : return mThread;
304 : }
305 :
306 : // Get the STS thread
307 0 : nsIEventTarget* GetSTSThread() {
308 0 : PC_AUTO_ENTER_API_CALL_NO_CHECK();
309 0 : return mSTSThread;
310 : }
311 :
312 0 : nsPIDOMWindowInner* GetWindow() const {
313 0 : PC_AUTO_ENTER_API_CALL_NO_CHECK();
314 0 : return mWindow;
315 : }
316 :
317 : // Initialize PeerConnection from a PeerConnectionConfiguration object
318 : // (used directly by unit-tests, and indirectly by the JS entry point)
319 : // This is necessary because RTCConfiguration can't be used by unit-tests
320 : nsresult Initialize(PeerConnectionObserver& aObserver,
321 : nsGlobalWindow* aWindow,
322 : const PeerConnectionConfiguration& aConfiguration,
323 : nsISupports* aThread);
324 :
325 : // Initialize PeerConnection from an RTCConfiguration object (JS entrypoint)
326 : void Initialize(PeerConnectionObserver& aObserver,
327 : nsGlobalWindow& aWindow,
328 : const RTCConfiguration& aConfiguration,
329 : nsISupports* aThread,
330 : ErrorResult &rv);
331 :
332 : void SetCertificate(mozilla::dom::RTCCertificate& aCertificate);
333 : const RefPtr<mozilla::dom::RTCCertificate>& Certificate() const;
334 : // This is a hack to support external linkage.
335 : RefPtr<DtlsIdentity> Identity() const;
336 :
337 0 : NS_IMETHODIMP_TO_ERRORRESULT(CreateOffer, ErrorResult &rv,
338 : const RTCOfferOptions& aOptions)
339 : {
340 0 : rv = CreateOffer(aOptions);
341 0 : }
342 :
343 : NS_IMETHODIMP CreateAnswer();
344 0 : void CreateAnswer(ErrorResult &rv)
345 : {
346 0 : rv = CreateAnswer();
347 0 : }
348 :
349 : NS_IMETHODIMP CreateOffer(
350 : const mozilla::JsepOfferOptions& aConstraints);
351 :
352 : NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP);
353 :
354 0 : void SetLocalDescription (int32_t aAction, const nsAString& aSDP, ErrorResult &rv)
355 : {
356 0 : rv = SetLocalDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get());
357 0 : }
358 :
359 : nsresult CreateNewRemoteTracks(RefPtr<PeerConnectionObserver>& aPco);
360 :
361 : void RemoveOldRemoteTracks(RefPtr<PeerConnectionObserver>& aPco);
362 :
363 : NS_IMETHODIMP SetRemoteDescription (int32_t aAction, const char* aSDP);
364 :
365 0 : void SetRemoteDescription (int32_t aAction, const nsAString& aSDP, ErrorResult &rv)
366 : {
367 0 : rv = SetRemoteDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get());
368 0 : }
369 :
370 0 : NS_IMETHODIMP_TO_ERRORRESULT(GetStats, ErrorResult &rv,
371 : mozilla::dom::MediaStreamTrack *aSelector)
372 : {
373 0 : rv = GetStats(aSelector);
374 0 : }
375 :
376 : NS_IMETHODIMP AddIceCandidate(const char* aCandidate, const char* aMid,
377 : unsigned short aLevel);
378 :
379 0 : void AddIceCandidate(const nsAString& aCandidate, const nsAString& aMid,
380 : unsigned short aLevel, ErrorResult &rv)
381 : {
382 0 : rv = AddIceCandidate(NS_ConvertUTF16toUTF8(aCandidate).get(),
383 0 : NS_ConvertUTF16toUTF8(aMid).get(), aLevel);
384 0 : }
385 :
386 : void UpdateNetworkState(bool online);
387 :
388 : NS_IMETHODIMP CloseStreams();
389 :
390 0 : void CloseStreams(ErrorResult &rv)
391 : {
392 0 : rv = CloseStreams();
393 0 : }
394 :
395 0 : NS_IMETHODIMP_TO_ERRORRESULT(AddTrack, ErrorResult &rv,
396 : mozilla::dom::MediaStreamTrack& aTrack,
397 : const mozilla::dom::Sequence<mozilla::OwningNonNull<DOMMediaStream>>& aStreams)
398 : {
399 0 : rv = AddTrack(aTrack, aStreams);
400 0 : }
401 :
402 0 : NS_IMETHODIMP_TO_ERRORRESULT(RemoveTrack, ErrorResult &rv,
403 : mozilla::dom::MediaStreamTrack& aTrack)
404 : {
405 0 : rv = RemoveTrack(aTrack);
406 0 : }
407 :
408 : nsresult
409 : AddTrack(mozilla::dom::MediaStreamTrack& aTrack, DOMMediaStream& aStream);
410 :
411 0 : NS_IMETHODIMP_TO_ERRORRESULT(InsertDTMF, ErrorResult &rv,
412 : dom::RTCRtpSender& sender,
413 : const nsAString& tones,
414 : uint32_t duration, uint32_t interToneGap) {
415 0 : rv = InsertDTMF(sender, tones, duration, interToneGap);
416 0 : }
417 :
418 0 : NS_IMETHODIMP_TO_ERRORRESULT(GetDTMFToneBuffer, ErrorResult &rv,
419 : dom::RTCRtpSender& sender,
420 : nsAString& outToneBuffer) {
421 0 : rv = GetDTMFToneBuffer(sender, outToneBuffer);
422 0 : }
423 :
424 0 : NS_IMETHODIMP_TO_ERRORRESULT(ReplaceTrack, ErrorResult &rv,
425 : mozilla::dom::MediaStreamTrack& aThisTrack,
426 : mozilla::dom::MediaStreamTrack& aWithTrack)
427 : {
428 0 : rv = ReplaceTrack(aThisTrack, aWithTrack);
429 0 : }
430 :
431 0 : NS_IMETHODIMP_TO_ERRORRESULT(SetParameters, ErrorResult &rv,
432 : dom::MediaStreamTrack& aTrack,
433 : const dom::RTCRtpParameters& aParameters)
434 : {
435 0 : rv = SetParameters(aTrack, aParameters);
436 0 : }
437 :
438 0 : NS_IMETHODIMP_TO_ERRORRESULT(GetParameters, ErrorResult &rv,
439 : dom::MediaStreamTrack& aTrack,
440 : dom::RTCRtpParameters& aOutParameters)
441 : {
442 0 : rv = GetParameters(aTrack, aOutParameters);
443 0 : }
444 :
445 : nsresult
446 : SetParameters(dom::MediaStreamTrack& aTrack,
447 : const std::vector<JsepTrack::JsConstraints>& aConstraints);
448 :
449 : nsresult
450 : GetParameters(dom::MediaStreamTrack& aTrack,
451 : std::vector<JsepTrack::JsConstraints>* aOutConstraints);
452 :
453 : // test-only: called from simulcast mochitests.
454 : NS_IMETHODIMP_TO_ERRORRESULT(AddRIDExtension, ErrorResult &rv,
455 : dom::MediaStreamTrack& aRecvTrack,
456 : unsigned short aExtensionId)
457 : {
458 : rv = AddRIDExtension(aRecvTrack, aExtensionId);
459 : }
460 :
461 : // test-only: called from simulcast mochitests.
462 : NS_IMETHODIMP_TO_ERRORRESULT(AddRIDFilter, ErrorResult& rv,
463 : dom::MediaStreamTrack& aRecvTrack,
464 : const nsAString& aRid)
465 : {
466 : rv = AddRIDFilter(aRecvTrack, aRid);
467 : }
468 :
469 0 : nsresult GetPeerIdentity(nsAString& peerIdentity)
470 : {
471 0 : if (mPeerIdentity) {
472 0 : peerIdentity = mPeerIdentity->ToString();
473 0 : return NS_OK;
474 : }
475 :
476 0 : peerIdentity.SetIsVoid(true);
477 0 : return NS_OK;
478 : }
479 :
480 0 : const PeerIdentity* GetPeerIdentity() const { return mPeerIdentity; }
481 : nsresult SetPeerIdentity(const nsAString& peerIdentity);
482 :
483 0 : const std::string& GetIdAsAscii() const
484 : {
485 0 : return mName;
486 : }
487 :
488 0 : nsresult GetId(nsAString& id)
489 : {
490 0 : id = NS_ConvertASCIItoUTF16(mName.c_str());
491 0 : return NS_OK;
492 : }
493 :
494 0 : nsresult SetId(const nsAString& id)
495 : {
496 0 : mName = NS_ConvertUTF16toUTF8(id).get();
497 0 : return NS_OK;
498 : }
499 :
500 : // this method checks to see if we've made a promise to protect media.
501 0 : bool PrivacyRequested() const { return mPrivacyRequested; }
502 :
503 : NS_IMETHODIMP GetFingerprint(char** fingerprint);
504 0 : void GetFingerprint(nsAString& fingerprint)
505 : {
506 : char *tmp;
507 0 : GetFingerprint(&tmp);
508 0 : fingerprint.AssignASCII(tmp);
509 0 : delete[] tmp;
510 0 : }
511 :
512 : NS_IMETHODIMP GetLocalDescription(nsAString& aSDP);
513 : NS_IMETHODIMP GetCurrentLocalDescription(nsAString& aSDP);
514 : NS_IMETHODIMP GetPendingLocalDescription(nsAString& aSDP);
515 :
516 : NS_IMETHODIMP GetRemoteDescription(nsAString& aSDP);
517 : NS_IMETHODIMP GetCurrentRemoteDescription(nsAString& aSDP);
518 : NS_IMETHODIMP GetPendingRemoteDescription(nsAString& aSDP);
519 :
520 : NS_IMETHODIMP SignalingState(mozilla::dom::PCImplSignalingState* aState);
521 :
522 0 : mozilla::dom::PCImplSignalingState SignalingState()
523 : {
524 : mozilla::dom::PCImplSignalingState state;
525 0 : SignalingState(&state);
526 0 : return state;
527 : }
528 :
529 : NS_IMETHODIMP IceConnectionState(
530 : mozilla::dom::PCImplIceConnectionState* aState);
531 :
532 0 : mozilla::dom::PCImplIceConnectionState IceConnectionState()
533 : {
534 : mozilla::dom::PCImplIceConnectionState state;
535 0 : IceConnectionState(&state);
536 0 : return state;
537 : }
538 :
539 : NS_IMETHODIMP IceGatheringState(
540 : mozilla::dom::PCImplIceGatheringState* aState);
541 :
542 0 : mozilla::dom::PCImplIceGatheringState IceGatheringState()
543 : {
544 : mozilla::dom::PCImplIceGatheringState state;
545 0 : IceGatheringState(&state);
546 0 : return state;
547 : }
548 :
549 : NS_IMETHODIMP Close();
550 :
551 : void Close(ErrorResult &rv)
552 : {
553 : rv = Close();
554 : }
555 :
556 : bool PluginCrash(uint32_t aPluginID,
557 : const nsAString& aPluginName);
558 :
559 : void RecordEndOfCallTelemetry() const;
560 :
561 : nsresult InitializeDataChannel();
562 :
563 : NS_IMETHODIMP_TO_ERRORRESULT_RETREF(nsDOMDataChannel,
564 : CreateDataChannel, ErrorResult &rv,
565 : const nsAString& aLabel,
566 : const nsAString& aProtocol,
567 : uint16_t aType,
568 : bool outOfOrderAllowed,
569 : uint16_t aMaxTime,
570 : uint16_t aMaxNum,
571 : bool aExternalNegotiated,
572 : uint16_t aStream);
573 :
574 : NS_IMETHODIMP_TO_ERRORRESULT(GetLocalStreams, ErrorResult &rv,
575 : nsTArray<RefPtr<DOMMediaStream > >& result)
576 : {
577 : rv = GetLocalStreams(result);
578 : }
579 :
580 : NS_IMETHODIMP_TO_ERRORRESULT(GetRemoteStreams, ErrorResult &rv,
581 : nsTArray<RefPtr<DOMMediaStream > >& result)
582 : {
583 : rv = GetRemoteStreams(result);
584 : }
585 :
586 : // Called whenever something is unrecognized by the parser
587 : // May be called more than once and does not necessarily mean
588 : // that parsing was stopped, only that something was unrecognized.
589 : void OnSdpParseError(const char* errorMessage);
590 :
591 : // Called when OnLocal/RemoteDescriptionSuccess/Error
592 : // is called to start the list over.
593 : void ClearSdpParseErrorMessages();
594 :
595 : // Called to retreive the list of parsing errors.
596 : const std::vector<std::string> &GetSdpParseErrors();
597 :
598 : // Sets the RTC Signaling State
599 : void SetSignalingState_m(mozilla::dom::PCImplSignalingState aSignalingState,
600 : bool rollback = false);
601 :
602 : // Updates the RTC signaling state based on the JsepSession state
603 : void UpdateSignalingState(bool rollback = false);
604 :
605 : bool IsClosed() const;
606 : // called when DTLS connects; we only need this once
607 : nsresult SetDtlsConnected(bool aPrivacyRequested);
608 :
609 : bool HasMedia() const;
610 :
611 : // initialize telemetry for when calls start
612 : void startCallTelem();
613 :
614 : nsresult BuildStatsQuery_m(
615 : mozilla::dom::MediaStreamTrack *aSelector,
616 : RTCStatsQuery *query);
617 :
618 : static nsresult ExecuteStatsQuery_s(RTCStatsQuery *query);
619 :
620 : // for monitoring changes in track ownership
621 : // PeerConnectionMedia can't do it because it doesn't know about principals
622 : virtual void PrincipalChanged(dom::MediaStreamTrack* aTrack) override;
623 :
624 : static std::string GetStreamId(const DOMMediaStream& aStream);
625 : static std::string GetTrackId(const dom::MediaStreamTrack& track);
626 :
627 : void OnMediaError(const std::string& aError);
628 :
629 : private:
630 : virtual ~PeerConnectionImpl();
631 : PeerConnectionImpl(const PeerConnectionImpl&rhs);
632 : PeerConnectionImpl& operator=(PeerConnectionImpl);
633 : nsresult CalculateFingerprint(const std::string& algorithm,
634 : std::vector<uint8_t>* fingerprint) const;
635 : nsresult ConfigureJsepSessionCodecs();
636 :
637 : NS_IMETHODIMP EnsureDataConnection(uint16_t aLocalPort, uint16_t aNumstreams,
638 : uint32_t aMaxMessageSize, bool aMMSSet);
639 :
640 : nsresult CloseInt();
641 : nsresult CheckApiState(bool assert_ice_ready) const;
642 0 : void CheckThread() const {
643 0 : MOZ_ASSERT(CheckThreadInt(), "Wrong thread");
644 0 : }
645 0 : bool CheckThreadInt() const {
646 : bool on;
647 0 : NS_ENSURE_SUCCESS(mThread->IsOnCurrentThread(&on), false);
648 0 : NS_ENSURE_TRUE(on, false);
649 0 : return true;
650 : }
651 :
652 : // test-only: called from AddRIDExtension and AddRIDFilter
653 : // for simulcast mochitests.
654 : RefPtr<MediaPipeline> GetMediaPipelineForTrack(
655 : dom::MediaStreamTrack& aRecvTrack);
656 :
657 : nsresult GetTimeSinceEpoch(DOMHighResTimeStamp *result);
658 :
659 : // Shut down media - called on main thread only
660 : void ShutdownMedia();
661 :
662 : void CandidateReady(const std::string& candidate, uint16_t level);
663 : void SendLocalIceCandidateToContent(uint16_t level,
664 : const std::string& mid,
665 : const std::string& candidate);
666 :
667 : nsresult GetDatachannelParameters(
668 : uint32_t* channels,
669 : uint16_t* localport,
670 : uint16_t* remoteport,
671 : uint32_t* maxmessagesize,
672 : bool* mmsset,
673 : uint16_t* level) const;
674 :
675 : static void DeferredAddTrackToJsepSession(const std::string& pcHandle,
676 : SdpMediaSection::MediaType type,
677 : const std::string& streamId,
678 : const std::string& trackId);
679 :
680 : nsresult AddTrackToJsepSession(SdpMediaSection::MediaType type,
681 : const std::string& streamId,
682 : const std::string& trackId);
683 :
684 : nsresult SetupIceRestart();
685 : nsresult RollbackIceRestart();
686 : void FinalizeIceRestart();
687 :
688 : static void GetStatsForPCObserver_s(
689 : const std::string& pcHandle,
690 : nsAutoPtr<RTCStatsQuery> query);
691 :
692 : // Sends an RTCStatsReport to JS. Must run on main thread.
693 : static void DeliverStatsReportToPCObserver_m(
694 : const std::string& pcHandle,
695 : nsresult result,
696 : nsAutoPtr<RTCStatsQuery> query);
697 :
698 : // When ICE completes, we record a bunch of statistics that outlive the
699 : // PeerConnection. This is just telemetry right now, but this can also
700 : // include things like dumping the RLogConnector somewhere, saving away
701 : // an RTCStatsReport somewhere so it can be inspected after the call is over,
702 : // or other things.
703 : void RecordLongtermICEStatistics();
704 :
705 : void OnNegotiationNeeded();
706 : static void MaybeFireNegotiationNeeded_static(const std::string& pcHandle);
707 : void MaybeFireNegotiationNeeded();
708 :
709 : // Timecard used to measure processing time. This should be the first class
710 : // attribute so that we accurately measure the time required to instantiate
711 : // any other attributes of this class.
712 : Timecard *mTimeCard;
713 :
714 : mozilla::dom::PCImplSignalingState mSignalingState;
715 :
716 : // ICE State
717 : mozilla::dom::PCImplIceConnectionState mIceConnectionState;
718 : mozilla::dom::PCImplIceGatheringState mIceGatheringState;
719 :
720 : // DTLS
721 : // this is true if we have been connected ever, see SetDtlsConnected
722 : bool mDtlsConnected;
723 :
724 : nsCOMPtr<nsIThread> mThread;
725 : // TODO: Remove if we ever properly wire PeerConnection for cycle-collection.
726 : nsWeakPtr mPCObserver;
727 :
728 : nsCOMPtr<nsPIDOMWindowInner> mWindow;
729 :
730 : // The SDP sent in from JS
731 : std::string mLocalRequestedSDP;
732 : std::string mRemoteRequestedSDP;
733 :
734 : // DTLS fingerprint
735 : std::string mFingerprint;
736 : std::string mRemoteFingerprint;
737 :
738 : // identity-related fields
739 : // The entity on the other end of the peer-to-peer connection;
740 : // void if they are not yet identified, and no identity setting has been set
741 : RefPtr<PeerIdentity> mPeerIdentity;
742 : // The certificate we are using.
743 : RefPtr<mozilla::dom::RTCCertificate> mCertificate;
744 : // Whether an app should be prevented from accessing media produced by the PC
745 : // If this is true, then media will not be sent until mPeerIdentity matches
746 : // local streams PeerIdentity; and remote streams are protected from content
747 : //
748 : // This can be false if mPeerIdentity is set, in the case where identity is
749 : // provided, but the media is not protected from the app on either side
750 : bool mPrivacyRequested;
751 :
752 : // A handle to refer to this PC with
753 : std::string mHandle;
754 :
755 : // A name for this PC that we are willing to expose to content.
756 : std::string mName;
757 :
758 : // The target to run stuff on
759 : nsCOMPtr<nsIEventTarget> mSTSThread;
760 :
761 : // DataConnection that's used to get all the DataChannels
762 : RefPtr<mozilla::DataChannelConnection> mDataConnection;
763 :
764 : bool mAllowIceLoopback;
765 : bool mAllowIceLinkLocal;
766 : bool mForceIceTcp;
767 : RefPtr<PeerConnectionMedia> mMedia;
768 :
769 : // The JSEP negotiation session.
770 : mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
771 : mozilla::UniquePtr<mozilla::JsepSession> mJsepSession;
772 : std::string mPreviousIceUfrag; // used during rollback of ice restart
773 : std::string mPreviousIcePwd; // used during rollback of ice restart
774 :
775 : // Start time of ICE, used for telemetry
776 : mozilla::TimeStamp mIceStartTime;
777 : // Start time of call used for Telemetry
778 : mozilla::TimeStamp mStartTime;
779 :
780 : bool mHaveConfiguredCodecs;
781 :
782 : bool mHaveDataStream;
783 :
784 : unsigned int mAddCandidateErrorCount;
785 :
786 : bool mTrickle;
787 :
788 : bool mNegotiationNeeded;
789 :
790 : bool mPrivateWindow;
791 :
792 : // storage for Telemetry data
793 : uint16_t mMaxReceiving[SdpMediaSection::kMediaTypes];
794 : uint16_t mMaxSending[SdpMediaSection::kMediaTypes];
795 :
796 : // DTMF
797 0 : struct DTMFState {
798 : PeerConnectionImpl* mPeerConnectionImpl;
799 : nsCOMPtr<nsITimer> mSendTimer;
800 : nsString mTrackId;
801 : nsString mTones;
802 : size_t mLevel;
803 : uint32_t mDuration;
804 : uint32_t mInterToneGap;
805 : };
806 :
807 : static void
808 : DTMFSendTimerCallback_m(nsITimer* timer, void*);
809 :
810 : nsTArray<DTMFState> mDTMFStates;
811 :
812 : public:
813 : //these are temporary until the DataChannel Listen/Connect API is removed
814 : unsigned short listenPort;
815 : unsigned short connectPort;
816 : char *connectStr; // XXX ownership/free
817 : };
818 :
819 : // This is what is returned when you acquire on a handle
820 0 : class PeerConnectionWrapper
821 : {
822 : public:
823 : explicit PeerConnectionWrapper(const std::string& handle);
824 :
825 0 : PeerConnectionImpl *impl() { return impl_; }
826 :
827 : private:
828 : RefPtr<PeerConnectionImpl> impl_;
829 : };
830 :
831 : } // end mozilla namespace
832 :
833 : #undef NS_IMETHODIMP_TO_ERRORRESULT
834 : #undef NS_IMETHODIMP_TO_ERRORRESULT_RETREF
835 : #endif // _PEER_CONNECTION_IMPL_H_
|