| 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 | |
| 52 | namespace WebCore { |
| 53 | |
| 54 | class MediaStream; |
| 55 | class MediaStreamTrack; |
| 56 | class PeerConnectionBackend; |
| 57 | class RTCController; |
| 58 | class RTCIceCandidate; |
| 59 | class RTCPeerConnectionErrorCallback; |
| 60 | class RTCSessionDescription; |
| 61 | class RTCStatsCallback; |
| 62 | |
| 63 | struct RTCAnswerOptions; |
| 64 | struct RTCOfferOptions; |
| 65 | struct RTCRtpParameters; |
| 66 | |
| 67 | struct RTCRtpTransceiverInit { |
| 68 | RTCRtpTransceiverDirection direction { RTCRtpTransceiverDirection::Sendrecv }; |
| 69 | Vector<RefPtr<MediaStream>> streams; |
| 70 | }; |
| 71 | |
| 72 | class 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); |
| 81 | public: |
| 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 | |
| 185 | private: |
| 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 | |