| /* |
| * Copyright (C) 2012 Google Inc. All rights reserved. |
| * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). |
| * Copyright (C) 2015 Ericsson AB. All rights reserved. |
| * Copyright (C) 2017 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * 3. Neither the name of Google Inc. nor the names of its contributors |
| * may be used to endorse or promote products derived from this |
| * software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #pragma once |
| |
| #if ENABLE(WEB_RTC) |
| |
| #include "ActiveDOMObject.h" |
| #include "EventTarget.h" |
| #include "MediaEndpointConfiguration.h" |
| #include "MediaStream.h" |
| #include "PeerConnectionBackend.h" |
| #include "RTCConfiguration.h" |
| #include "RTCDataChannel.h" |
| #include "RTCIceConnectionState.h" |
| #include "RTCIceGatheringState.h" |
| #include "RTCLocalSessionDescriptionInit.h" |
| #include "RTCPeerConnectionState.h" |
| #include "RTCRtpEncodingParameters.h" |
| #include "RTCRtpTransceiver.h" |
| #include "RTCSessionDescriptionInit.h" |
| #include "RTCSignalingState.h" |
| #include <JavaScriptCore/Forward.h> |
| #include <wtf/LoggerHelper.h> |
| #include <wtf/WeakPtr.h> |
| |
| namespace WebCore { |
| |
| class DOMPromiseDeferredBase; |
| class MediaStream; |
| class MediaStreamTrack; |
| class RTCController; |
| class RTCDtlsTransport; |
| class RTCDtlsTransportBackend; |
| class RTCIceCandidate; |
| class RTCIceTransportBackend; |
| class RTCPeerConnectionErrorCallback; |
| class RTCSctpTransport; |
| class RTCSessionDescription; |
| class RTCStatsCallback; |
| |
| struct RTCAnswerOptions; |
| struct RTCOfferOptions; |
| struct RTCRtpParameters; |
| struct RTCIceCandidateInit; |
| struct RTCSessionDescriptionInit; |
| |
| struct RTCRtpTransceiverInit { |
| RTCRtpTransceiverDirection direction { RTCRtpTransceiverDirection::Sendrecv }; |
| Vector<RefPtr<MediaStream>> streams; |
| Vector<RTCRtpEncodingParameters> sendEncodings; |
| }; |
| |
| class RTCPeerConnection final |
| : public RefCounted<RTCPeerConnection> |
| , public EventTargetWithInlineData |
| , public ActiveDOMObject |
| #if !RELEASE_LOG_DISABLED |
| , private LoggerHelper |
| #endif |
| { |
| WTF_MAKE_ISO_ALLOCATED(RTCPeerConnection); |
| public: |
| static ExceptionOr<Ref<RTCPeerConnection>> create(Document&, RTCConfiguration&&); |
| virtual ~RTCPeerConnection(); |
| |
| using DataChannelInit = RTCDataChannelInit; |
| |
| struct CertificateParameters { |
| String name; |
| String hash; |
| String namedCurve; |
| std::optional<uint32_t> modulusLength; |
| RefPtr<Uint8Array> publicExponent; |
| std::optional<double> expires; |
| }; |
| |
| using AlgorithmIdentifier = std::variant<JSC::Strong<JSC::JSObject>, String>; |
| static void generateCertificate(JSC::JSGlobalObject&, AlgorithmIdentifier&&, DOMPromiseDeferred<IDLInterface<RTCCertificate>>&&); |
| |
| // 4.3.2 RTCPeerConnection Interface |
| void createOffer(RTCOfferOptions&&, Ref<DeferredPromise>&&); |
| void createAnswer(RTCAnswerOptions&&, Ref<DeferredPromise>&&); |
| |
| void setLocalDescription(std::optional<RTCLocalSessionDescriptionInit>&&, Ref<DeferredPromise>&&); |
| RefPtr<RTCSessionDescription> localDescription() const { return m_pendingLocalDescription ? m_pendingLocalDescription.get() : m_currentLocalDescription.get(); } |
| RefPtr<RTCSessionDescription> currentLocalDescription() const { return m_currentLocalDescription.get(); } |
| RefPtr<RTCSessionDescription> pendingLocalDescription() const { return m_pendingLocalDescription.get(); } |
| |
| void setRemoteDescription(RTCSessionDescriptionInit&&, Ref<DeferredPromise>&&); |
| RTCSessionDescription* remoteDescription() const { return m_pendingRemoteDescription ? m_pendingRemoteDescription.get() : m_currentRemoteDescription.get(); } |
| RTCSessionDescription* currentRemoteDescription() const { return m_currentRemoteDescription.get(); } |
| RTCSessionDescription* pendingRemoteDescription() const { return m_pendingRemoteDescription.get(); } |
| |
| using Candidate = std::optional<std::variant<RTCIceCandidateInit, RefPtr<RTCIceCandidate>>>; |
| void addIceCandidate(Candidate&&, Ref<DeferredPromise>&&); |
| |
| RTCSignalingState signalingState() const { return m_signalingState; } |
| RTCIceGatheringState iceGatheringState() const { return m_iceGatheringState; } |
| RTCIceConnectionState iceConnectionState() const { return m_iceConnectionState; } |
| RTCPeerConnectionState connectionState() const { return m_connectionState; } |
| std::optional<bool> canTrickleIceCandidates() const; |
| |
| void restartIce() { m_backend->restartIce(); } |
| const RTCConfiguration& getConfiguration() const { return m_configuration; } |
| ExceptionOr<void> setConfiguration(RTCConfiguration&&); |
| void close(); |
| |
| bool isClosed() const { return m_connectionState == RTCPeerConnectionState::Closed; } |
| bool isStopped() const { return m_isStopped; } |
| |
| void addInternalTransceiver(Ref<RTCRtpTransceiver>&&); |
| |
| // 5.1 RTCPeerConnection extensions |
| Vector<std::reference_wrapper<RTCRtpSender>> getSenders() const; |
| Vector<std::reference_wrapper<RTCRtpReceiver>> getReceivers() const; |
| const Vector<RefPtr<RTCRtpTransceiver>>& getTransceivers() const; |
| |
| const Vector<RefPtr<RTCRtpTransceiver>>& currentTransceivers() const { return m_transceiverSet.list(); } |
| |
| ExceptionOr<Ref<RTCRtpSender>> addTrack(Ref<MediaStreamTrack>&&, const FixedVector<std::reference_wrapper<MediaStream>>&); |
| ExceptionOr<void> removeTrack(RTCRtpSender&); |
| |
| using AddTransceiverTrackOrKind = std::variant<RefPtr<MediaStreamTrack>, String>; |
| ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(AddTransceiverTrackOrKind&&, const RTCRtpTransceiverInit&); |
| |
| // 6.1 Peer-to-peer data API |
| ExceptionOr<Ref<RTCDataChannel>> createDataChannel(String&&, RTCDataChannelInit&&); |
| |
| // 8.2 Statistics API |
| void getStats(MediaStreamTrack*, Ref<DeferredPromise>&&); |
| // Used for testing |
| WEBCORE_EXPORT void gatherDecoderImplementationName(Function<void(String&&)>&&); |
| |
| // EventTarget |
| EventTargetInterface eventTargetInterface() const final { return RTCPeerConnectionEventTargetInterfaceType; } |
| ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } |
| |
| using RefCounted::ref; |
| using RefCounted::deref; |
| |
| // Used for testing with a mock |
| WEBCORE_EXPORT void emulatePlatformEvent(const String& action); |
| |
| // API used by PeerConnectionBackend and relatives |
| void updateIceGatheringState(RTCIceGatheringState); |
| void updateIceConnectionState(RTCIceConnectionState); |
| void updateConnectionState(); |
| |
| void updateNegotiationNeededFlag(std::optional<uint32_t>); |
| |
| void scheduleEvent(Ref<Event>&&); |
| |
| void disableICECandidateFiltering() { m_backend->disableICECandidateFiltering(); } |
| void enableICECandidateFiltering() { m_backend->enableICECandidateFiltering(); } |
| |
| void clearController() { m_controller = nullptr; } |
| |
| Document* document(); |
| |
| void updateDescriptions(PeerConnectionBackend::DescriptionStates&&); |
| void updateTransceiversAfterSuccessfulLocalDescription(); |
| void updateTransceiversAfterSuccessfulRemoteDescription(); |
| void updateSctpBackend(std::unique_ptr<RTCSctpTransportBackend>&&); |
| |
| void processIceTransportStateChange(RTCIceTransport&); |
| void processIceTransportChanges(); |
| |
| RTCSctpTransport* sctp() { return m_sctpTransport.get(); } |
| |
| // EventTarget implementation. |
| void dispatchEvent(Event&) final; |
| |
| #if !RELEASE_LOG_DISABLED |
| const Logger& logger() const final { return m_logger.get(); } |
| const void* logIdentifier() const final { return m_logIdentifier; } |
| const char* logClassName() const final { return "RTCPeerConnection"; } |
| WTFLogChannel& logChannel() const final; |
| #endif |
| |
| private: |
| RTCPeerConnection(Document&); |
| |
| ExceptionOr<void> initializeConfiguration(RTCConfiguration&&); |
| |
| void registerToController(RTCController&); |
| void unregisterFromController(); |
| |
| friend class Internals; |
| void applyRotationForOutgoingVideoSources() { m_backend->applyRotationForOutgoingVideoSources(); } |
| |
| // EventTarget implementation. |
| void refEventTarget() final { ref(); } |
| void derefEventTarget() final { deref(); } |
| |
| // ActiveDOMObject |
| WEBCORE_EXPORT void stop() final; |
| const char* activeDOMObjectName() const final; |
| void suspend(ReasonForSuspension) final; |
| void resume() final; |
| bool virtualHasPendingActivity() const final; |
| |
| bool updateIceConnectionStateFromIceTransports(); |
| RTCIceConnectionState computeIceConnectionStateFromIceTransports(); |
| RTCPeerConnectionState computeConnectionState(); |
| |
| bool doClose(); |
| void doStop(); |
| |
| void getStats(RTCRtpSender& sender, Ref<DeferredPromise>&& promise) { m_backend->getStats(sender, WTFMove(promise)); } |
| |
| ExceptionOr<Vector<MediaEndpointConfiguration::CertificatePEM>> certificatesFromConfiguration(const RTCConfiguration&); |
| void chainOperation(Ref<DeferredPromise>&&, Function<void(Ref<DeferredPromise>&&)>&&); |
| friend class RTCRtpSender; |
| |
| ExceptionOr<Vector<MediaEndpointConfiguration::IceServerInfo>> iceServersFromConfiguration(RTCConfiguration& newConfiguration, const RTCConfiguration* existingConfiguration, bool isLocalDescriptionSet); |
| |
| Ref<RTCIceTransport> getOrCreateIceTransport(UniqueRef<RTCIceTransportBackend>&&); |
| RefPtr<RTCDtlsTransport> getOrCreateDtlsTransport(std::unique_ptr<RTCDtlsTransportBackend>&&); |
| void updateTransceiverTransports(); |
| |
| void setSignalingState(RTCSignalingState); |
| |
| bool m_isStopped { false }; |
| RTCSignalingState m_signalingState { RTCSignalingState::Stable }; |
| RTCIceGatheringState m_iceGatheringState { RTCIceGatheringState::New }; |
| RTCIceConnectionState m_iceConnectionState { RTCIceConnectionState::New }; |
| RTCPeerConnectionState m_connectionState { RTCPeerConnectionState::New }; |
| |
| #if !RELEASE_LOG_DISABLED |
| Ref<const Logger> m_logger; |
| const void* m_logIdentifier; |
| #endif |
| |
| RtpTransceiverSet m_transceiverSet; |
| |
| std::unique_ptr<PeerConnectionBackend> m_backend; |
| |
| RTCConfiguration m_configuration; |
| RTCController* m_controller { nullptr }; |
| Vector<RefPtr<RTCCertificate>> m_certificates; |
| bool m_shouldDelayTasks { false }; |
| Deque<std::pair<Ref<DeferredPromise>, Function<void(Ref<DeferredPromise>&&)>>> m_operations; |
| bool m_hasPendingOperation { false }; |
| std::optional<uint32_t> m_negotiationNeededEventId; |
| Vector<Ref<RTCDtlsTransport>> m_dtlsTransports; |
| Vector<Ref<RTCIceTransport>> m_iceTransports; |
| RefPtr<RTCSctpTransport> m_sctpTransport; |
| |
| RefPtr<RTCSessionDescription> m_currentLocalDescription; |
| RefPtr<RTCSessionDescription> m_pendingLocalDescription; |
| RefPtr<RTCSessionDescription> m_currentRemoteDescription; |
| RefPtr<RTCSessionDescription> m_pendingRemoteDescription; |
| |
| String m_lastCreatedOffer; |
| String m_lastCreatedAnswer; |
| }; |
| |
| } // namespace WebCore |
| |
| #endif // ENABLE(WEB_RTC) |