1/*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
4 * Copyright (C) 2015 Ericsson AB. All rights reserved.
5 * Copyright (C) 2017 Apple Inc. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer
15 * in the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of Google Inc. nor the names of its contributors
18 * may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#pragma once
35
36#if ENABLE(WEB_RTC)
37
38#include "ActiveDOMObject.h"
39#include "EventTarget.h"
40#include "MediaEndpointConfiguration.h"
41#include "MediaStream.h"
42#include "RTCConfiguration.h"
43#include "RTCDataChannel.h"
44#include "RTCIceConnectionState.h"
45#include "RTCIceGatheringState.h"
46#include "RTCPeerConnectionState.h"
47#include "RTCRtpTransceiver.h"
48#include "RTCSignalingState.h"
49#include <JavaScriptCore/Uint8Array.h>
50#include <wtf/LoggerHelper.h>
51
52namespace WebCore {
53
54class MediaStream;
55class MediaStreamTrack;
56class PeerConnectionBackend;
57class RTCController;
58class RTCIceCandidate;
59class RTCPeerConnectionErrorCallback;
60class RTCSessionDescription;
61class RTCStatsCallback;
62
63struct RTCAnswerOptions;
64struct RTCOfferOptions;
65struct RTCRtpParameters;
66
67struct RTCRtpTransceiverInit {
68 RTCRtpTransceiverDirection direction { RTCRtpTransceiverDirection::Sendrecv };
69 Vector<RefPtr<MediaStream>> streams;
70};
71
72class RTCPeerConnection final
73 : public RefCounted<RTCPeerConnection>
74 , public EventTargetWithInlineData
75 , public ActiveDOMObject
76#if !RELEASE_LOG_DISABLED
77 , private LoggerHelper
78#endif
79{
80 WTF_MAKE_ISO_ALLOCATED(RTCPeerConnection);
81public:
82 static Ref<RTCPeerConnection> create(ScriptExecutionContext&);
83 virtual ~RTCPeerConnection();
84
85 using DataChannelInit = RTCDataChannelInit;
86
87 ExceptionOr<void> initializeWith(Document&, RTCConfiguration&&);
88
89 struct CertificateParameters {
90 String name;
91 String hash;
92 String namedCurve;
93 Optional<uint32_t> modulusLength;
94 RefPtr<Uint8Array> publicExponent;
95 Optional<double> expires;
96 };
97
98 using AlgorithmIdentifier = Variant<JSC::Strong<JSC::JSObject>, String>;
99 static void generateCertificate(JSC::ExecState&, AlgorithmIdentifier&&, DOMPromiseDeferred<IDLInterface<RTCCertificate>>&&);
100
101 // 4.3.2 RTCPeerConnection Interface
102 void queuedCreateOffer(RTCOfferOptions&&, PeerConnection::SessionDescriptionPromise&&);
103 void queuedCreateAnswer(RTCAnswerOptions&&, PeerConnection::SessionDescriptionPromise&&);
104
105 void queuedSetLocalDescription(RTCSessionDescription&, DOMPromiseDeferred<void>&&);
106 RefPtr<RTCSessionDescription> localDescription() const;
107 RefPtr<RTCSessionDescription> currentLocalDescription() const;
108 RefPtr<RTCSessionDescription> pendingLocalDescription() const;
109
110 void queuedSetRemoteDescription(RTCSessionDescription&, DOMPromiseDeferred<void>&&);
111 RefPtr<RTCSessionDescription> remoteDescription() const;
112 RefPtr<RTCSessionDescription> currentRemoteDescription() const;
113 RefPtr<RTCSessionDescription> pendingRemoteDescription() const;
114
115 void queuedAddIceCandidate(RTCIceCandidate*, DOMPromiseDeferred<void>&&);
116
117 RTCSignalingState signalingState() const { return m_signalingState; }
118 RTCIceGatheringState iceGatheringState() const { return m_iceGatheringState; }
119 RTCIceConnectionState iceConnectionState() const { return m_iceConnectionState; }
120 RTCPeerConnectionState connectionState() const { return m_connectionState; }
121
122 const RTCConfiguration& getConfiguration() const { return m_configuration; }
123 ExceptionOr<void> setConfiguration(RTCConfiguration&&);
124 void close();
125
126 bool isClosed() const { return m_connectionState == RTCPeerConnectionState::Closed; }
127 bool isStopped() const { return m_isStopped; }
128
129 void addInternalTransceiver(Ref<RTCRtpTransceiver>&& transceiver) { m_transceiverSet->append(WTFMove(transceiver)); }
130
131 // 5.1 RTCPeerConnection extensions
132 Vector<std::reference_wrapper<RTCRtpSender>> getSenders() const;
133 Vector<std::reference_wrapper<RTCRtpReceiver>> getReceivers() const;
134 const Vector<RefPtr<RTCRtpTransceiver>>& getTransceivers() const;
135
136 const Vector<RefPtr<RTCRtpTransceiver>>& currentTransceivers() const { return m_transceiverSet->list(); }
137
138 ExceptionOr<Ref<RTCRtpSender>> addTrack(Ref<MediaStreamTrack>&&, const Vector<std::reference_wrapper<MediaStream>>&);
139 ExceptionOr<void> removeTrack(RTCRtpSender&);
140
141 using AddTransceiverTrackOrKind = Variant<RefPtr<MediaStreamTrack>, String>;
142 ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(AddTransceiverTrackOrKind&&, const RTCRtpTransceiverInit&);
143
144 // 6.1 Peer-to-peer data API
145 ExceptionOr<Ref<RTCDataChannel>> createDataChannel(ScriptExecutionContext&, String&&, RTCDataChannelInit&&);
146
147 // 8.2 Statistics API
148 void getStats(MediaStreamTrack*, Ref<DeferredPromise>&&);
149
150 // EventTarget
151 EventTargetInterface eventTargetInterface() const final { return RTCPeerConnectionEventTargetInterfaceType; }
152 ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
153
154 using RefCounted::ref;
155 using RefCounted::deref;
156
157 // Used for testing with a mock
158 WEBCORE_EXPORT void emulatePlatformEvent(const String& action);
159
160 // API used by PeerConnectionBackend and relatives
161 void addTransceiver(Ref<RTCRtpTransceiver>&&);
162 void setSignalingState(RTCSignalingState);
163 void updateIceGatheringState(RTCIceGatheringState);
164 void updateIceConnectionState(RTCIceConnectionState);
165
166 void scheduleNegotiationNeededEvent();
167
168 void fireEvent(Event&);
169
170 void disableICECandidateFiltering() { m_backend->disableICECandidateFiltering(); }
171 void enableICECandidateFiltering() { m_backend->enableICECandidateFiltering(); }
172
173 void clearController() { m_controller = nullptr; }
174
175 // ActiveDOMObject.
176 bool hasPendingActivity() const final;
177
178#if !RELEASE_LOG_DISABLED
179 const Logger& logger() const final { return m_logger.get(); }
180 const void* logIdentifier() const final { return m_logIdentifier; }
181 const char* logClassName() const final { return "RTCPeerConnection"; }
182 WTFLogChannel& logChannel() const final;
183#endif
184
185private:
186 RTCPeerConnection(ScriptExecutionContext&);
187
188 ExceptionOr<void> initializeConfiguration(RTCConfiguration&&);
189 Ref<RTCRtpTransceiver> completeAddTransceiver(Ref<RTCRtpSender>&&, const RTCRtpTransceiverInit&, const String& trackId, const String& trackKind);
190
191 void registerToController(RTCController&);
192 void unregisterFromController();
193
194 friend class Internals;
195 void applyRotationForOutgoingVideoSources() { m_backend->applyRotationForOutgoingVideoSources(); }
196
197 // EventTarget implementation.
198 void refEventTarget() final { ref(); }
199 void derefEventTarget() final { deref(); }
200 void dispatchEvent(Event&) final;
201
202 // ActiveDOMObject
203 WEBCORE_EXPORT void stop() final;
204 const char* activeDOMObjectName() const final;
205 bool canSuspendForDocumentSuspension() const final;
206
207 void updateConnectionState();
208 bool doClose();
209 void doStop();
210
211 ExceptionOr<Vector<MediaEndpointConfiguration::CertificatePEM>> certificatesFromConfiguration(const RTCConfiguration&);
212
213 bool m_isStopped { false };
214 RTCSignalingState m_signalingState { RTCSignalingState::Stable };
215 RTCIceGatheringState m_iceGatheringState { RTCIceGatheringState::New };
216 RTCIceConnectionState m_iceConnectionState { RTCIceConnectionState::New };
217 RTCPeerConnectionState m_connectionState { RTCPeerConnectionState::New };
218
219#if !RELEASE_LOG_DISABLED
220 Ref<const Logger> m_logger;
221 const void* m_logIdentifier;
222#endif
223
224 std::unique_ptr<RtpTransceiverSet> m_transceiverSet { std::unique_ptr<RtpTransceiverSet>(new RtpTransceiverSet()) };
225
226 std::unique_ptr<PeerConnectionBackend> m_backend;
227
228 RTCConfiguration m_configuration;
229 RTCController* m_controller { nullptr };
230 Vector<RefPtr<RTCCertificate>> m_certificates;
231 RefPtr<PendingActivity<RTCPeerConnection>> m_pendingActivity;
232};
233
234} // namespace WebCore
235
236#endif // ENABLE(WEB_RTC)
237