1/*
2 * Copyright (C) 2015 Ericsson AB. All rights reserved.
3 * Copyright (C) 2017 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * 3. Neither the name of Ericsson nor the names of its contributors
16 * may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#pragma once
33
34#if ENABLE(WEB_RTC)
35
36#include "JSDOMPromiseDeferred.h"
37#include "LibWebRTCProvider.h"
38#include "RTCRtpSendParameters.h"
39#include "RTCSessionDescription.h"
40#include "RTCSignalingState.h"
41#include <wtf/LoggerHelper.h>
42#include <wtf/WeakPtr.h>
43
44namespace WebCore {
45
46class Document;
47class MediaStream;
48class MediaStreamTrack;
49class PeerConnectionBackend;
50class RTCCertificate;
51class RTCDataChannelHandler;
52class RTCIceCandidate;
53class RTCPeerConnection;
54class RTCRtpReceiver;
55class RTCRtpSender;
56class RTCRtpTransceiver;
57class RTCSessionDescription;
58class RTCStatsReport;
59
60struct MediaEndpointConfiguration;
61struct RTCAnswerOptions;
62struct RTCDataChannelInit;
63struct RTCOfferOptions;
64struct RTCRtpTransceiverInit;
65
66namespace PeerConnection {
67using SessionDescriptionPromise = DOMPromiseDeferred<IDLDictionary<RTCSessionDescription::Init>>;
68using StatsPromise = DOMPromiseDeferred<IDLInterface<RTCStatsReport>>;
69}
70
71using CreatePeerConnectionBackend = std::unique_ptr<PeerConnectionBackend> (*)(RTCPeerConnection&);
72
73class PeerConnectionBackend
74 : public CanMakeWeakPtr<PeerConnectionBackend>
75#if !RELEASE_LOG_DISABLED
76 , private LoggerHelper
77#endif
78{
79public:
80 WEBCORE_EXPORT static CreatePeerConnectionBackend create;
81
82 static Optional<RTCRtpCapabilities> receiverCapabilities(ScriptExecutionContext&, const String& kind);
83 static Optional<RTCRtpCapabilities> senderCapabilities(ScriptExecutionContext&, const String& kind);
84
85 explicit PeerConnectionBackend(RTCPeerConnection&);
86 virtual ~PeerConnectionBackend() = default;
87
88 void createOffer(RTCOfferOptions&&, PeerConnection::SessionDescriptionPromise&&);
89 void createAnswer(RTCAnswerOptions&&, PeerConnection::SessionDescriptionPromise&&);
90 void setLocalDescription(RTCSessionDescription&, DOMPromiseDeferred<void>&&);
91 void setRemoteDescription(RTCSessionDescription&, DOMPromiseDeferred<void>&&);
92 void addIceCandidate(RTCIceCandidate*, DOMPromiseDeferred<void>&&);
93
94 virtual std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) = 0;
95
96 void stop();
97
98 virtual RefPtr<RTCSessionDescription> localDescription() const = 0;
99 virtual RefPtr<RTCSessionDescription> currentLocalDescription() const = 0;
100 virtual RefPtr<RTCSessionDescription> pendingLocalDescription() const = 0;
101
102 virtual RefPtr<RTCSessionDescription> remoteDescription() const = 0;
103 virtual RefPtr<RTCSessionDescription> currentRemoteDescription() const = 0;
104 virtual RefPtr<RTCSessionDescription> pendingRemoteDescription() const = 0;
105
106 virtual bool setConfiguration(MediaEndpointConfiguration&&) = 0;
107
108 virtual void getStats(Ref<DeferredPromise>&&) = 0;
109 virtual void getStats(RTCRtpSender&, Ref<DeferredPromise>&&) = 0;
110 virtual void getStats(RTCRtpReceiver&, Ref<DeferredPromise>&&) = 0;
111
112 virtual ExceptionOr<Ref<RTCRtpSender>> addTrack(MediaStreamTrack&, Vector<String>&&);
113 virtual void removeTrack(RTCRtpSender&) { }
114
115 virtual ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(const String&, const RTCRtpTransceiverInit&);
116 virtual ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(Ref<MediaStreamTrack>&&, const RTCRtpTransceiverInit&);
117
118 void markAsNeedingNegotiation();
119 bool isNegotiationNeeded() const { return m_negotiationNeeded; };
120 void clearNegotiationNeededState() { m_negotiationNeeded = false; };
121
122 virtual void emulatePlatformEvent(const String& action) = 0;
123
124 void newICECandidate(String&& sdp, String&& mid, unsigned short sdpMLineIndex, String&& serverURL);
125 void disableICECandidateFiltering();
126 void enableICECandidateFiltering();
127
128 virtual void applyRotationForOutgoingVideoSources() { }
129
130#if !RELEASE_LOG_DISABLED
131 const Logger& logger() const final { return m_logger.get(); }
132 const void* logIdentifier() const final { return m_logIdentifier; }
133 const char* logClassName() const override { return "PeerConnectionBackend"; }
134 WTFLogChannel& logChannel() const final;
135#endif
136
137 virtual bool isLocalDescriptionSet() const = 0;
138
139 void finishedRegisteringMDNSName(const String& ipAddress, const String& name);
140
141 struct CertificateInformation {
142 enum class Type { RSASSAPKCS1v15, ECDSAP256 };
143 struct RSA {
144 unsigned modulusLength;
145 int publicExponent;
146 };
147
148 static CertificateInformation RSASSA_PKCS1_v1_5()
149 {
150 return CertificateInformation { Type::RSASSAPKCS1v15 };
151 }
152
153 static CertificateInformation ECDSA_P256()
154 {
155 return CertificateInformation { Type::ECDSAP256 };
156 }
157
158 explicit CertificateInformation(Type type)
159 : type(type)
160 {
161 }
162
163 Type type;
164 Optional<double> expires;
165
166 Optional<RSA> rsaParameters;
167 };
168 static void generateCertificate(Document&, const CertificateInformation&, DOMPromiseDeferred<IDLInterface<RTCCertificate>>&&);
169
170 virtual void collectTransceivers() { };
171
172protected:
173 void fireICECandidateEvent(RefPtr<RTCIceCandidate>&&, String&& url);
174 void doneGatheringCandidates();
175
176 void updateSignalingState(RTCSignalingState);
177
178 void createOfferSucceeded(String&&);
179 void createOfferFailed(Exception&&);
180
181 void createAnswerSucceeded(String&&);
182 void createAnswerFailed(Exception&&);
183
184 void setLocalDescriptionSucceeded();
185 void setLocalDescriptionFailed(Exception&&);
186
187 void setRemoteDescriptionSucceeded();
188 void setRemoteDescriptionFailed(Exception&&);
189
190 void addIceCandidateSucceeded();
191 void addIceCandidateFailed(Exception&&);
192
193 String filterSDP(String&&) const;
194
195 struct PendingTrackEvent {
196 Ref<RTCRtpReceiver> receiver;
197 Ref<MediaStreamTrack> track;
198 Vector<RefPtr<MediaStream>> streams;
199 RefPtr<RTCRtpTransceiver> transceiver;
200 };
201 void addPendingTrackEvent(PendingTrackEvent&&);
202
203private:
204 virtual void doCreateOffer(RTCOfferOptions&&) = 0;
205 virtual void doCreateAnswer(RTCAnswerOptions&&) = 0;
206 virtual void doSetLocalDescription(RTCSessionDescription&) = 0;
207 virtual void doSetRemoteDescription(RTCSessionDescription&) = 0;
208 virtual void doAddIceCandidate(RTCIceCandidate&) = 0;
209 virtual void endOfIceCandidates(DOMPromiseDeferred<void>&& promise) { promise.resolve(); }
210 virtual void doStop() = 0;
211
212 void registerMDNSName(const String& ipAddress);
213
214protected:
215 RTCPeerConnection& m_peerConnection;
216
217private:
218 Optional<PeerConnection::SessionDescriptionPromise> m_offerAnswerPromise;
219 Optional<DOMPromiseDeferred<void>> m_setDescriptionPromise;
220 Optional<DOMPromiseDeferred<void>> m_addIceCandidatePromise;
221
222 bool m_shouldFilterICECandidates { true };
223 struct PendingICECandidate {
224 // Fields described in https://www.w3.org/TR/webrtc/#idl-def-rtcicecandidateinit.
225 String sdp;
226 String mid;
227 unsigned short sdpMLineIndex;
228 String serverURL;
229 };
230 Vector<PendingICECandidate> m_pendingICECandidates;
231
232 Vector<PendingTrackEvent> m_pendingTrackEvents;
233
234#if !RELEASE_LOG_DISABLED
235 Ref<const Logger> m_logger;
236 const void* m_logIdentifier;
237#endif
238 bool m_negotiationNeeded { false };
239 bool m_finishedGatheringCandidates { false };
240 uint64_t m_waitingForMDNSRegistration { 0 };
241};
242
243} // namespace WebCore
244
245#endif // ENABLE(WEB_RTC)
246