Changeset 248282 in webkit
- Timestamp:
- Aug 5, 2019, 5:34:14 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 2 deleted
- 26 edited
- 2 copied
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange-long.https-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https-expected.txt (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp (modified) (1 diff)
-
Source/WebCore/Modules/mediastream/PeerConnectionBackend.h (modified) (1 diff)
-
Source/WebCore/Modules/mediastream/RTCDTMFSender.cpp (modified) (4 diffs)
-
Source/WebCore/Modules/mediastream/RTCDTMFSender.h (modified) (4 diffs)
-
Source/WebCore/Modules/mediastream/RTCDTMFSender.idl (modified) (1 diff)
-
Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.cpp (modified) (1 diff)
-
Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.h (modified) (1 diff)
-
Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.idl (modified) (2 diffs)
-
Source/WebCore/Modules/mediastream/RTCRtpSender.cpp (modified) (3 diffs)
-
Source/WebCore/Modules/mediastream/RTCRtpSender.h (modified) (3 diffs)
-
Source/WebCore/Modules/mediastream/RTCRtpSender.idl (modified) (1 diff)
-
Source/WebCore/Modules/mediastream/RTCRtpSenderBackend.h (modified) (2 diffs)
-
Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp (modified) (2 diffs)
-
Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h (modified) (1 diff)
-
Source/WebCore/Sources.txt (modified) (1 diff)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (6 diffs)
-
Source/WebCore/dom/EventNames.in (modified) (1 diff)
-
Source/WebCore/dom/EventTargetFactory.in (modified) (1 diff)
-
Source/WebCore/page/RuntimeEnabledFeatures.h (modified) (2 diffs)
-
Source/WebCore/platform/mediastream/RTCDTMFSenderBackend.h (copied) (copied from trunk/Source/WebCore/Modules/mediastream/RTCRtpSenderBackend.h ) (2 diffs)
-
Source/WebCore/platform/mediastream/RTCDTMFSenderHandler.h (deleted)
-
Source/WebCore/platform/mediastream/RTCDTMFSenderHandlerClient.h (deleted)
-
Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCDTMFSenderBackend.cpp (added)
-
Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCDTMFSenderBackend.h (copied) (copied from trunk/Source/WebCore/Modules/mediastream/RTCRtpSenderBackend.h ) (2 diffs)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/Shared/WebPreferences.yaml (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r247788 r248282 1 2019-08-05 Youenn Fablet <youenn@apple.com> 2 3 Support RTCRtpSender.dtmf 4 https://bugs.webkit.org/show_bug.cgi?id=200431 5 6 Reviewed by Eric Carlson. 7 8 * web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt: 9 * web-platform-tests/webrtc/RTCDTMFSender-ontonechange-long.https-expected.txt: 10 * web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https-expected.txt: 11 1 12 2019-07-24 Alicia Boya García <aboya@igalia.com> 2 13 -
trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt
r237773 r248282 1 1 2 FAIL insertDTMF() should succeed if tones contains valid DTMF characters promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: RTCDTMFSender" 3 FAIL insertDTMF() should throw InvalidCharacterError if tones contains invalid DTMF characters promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: RTCDTMFSender" 4 FAIL insertDTMF() should throw InvalidStateError if transceiver is stopped assert_throws: function "() => dtmfSender.insertDTMF('')" threw object "TypeError: undefined is not an object (evaluating 'dtmfSender.insertDTMF')" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11 5 FAIL insertDTMF() should throw InvalidStateError if transceiver.currentDirection is recvonly assert_throws: function "() => dtmfSender.insertDTMF('')" threw object "TypeError: undefined is not an object (evaluating 'dtmfSender.insertDTMF')" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11 6 FAIL insertDTMF() should throw InvalidStateError if transceiver.currentDirection is inactive assert_throws: function "() => dtmfSender.insertDTMF('')" threw object "TypeError: undefined is not an object (evaluating 'dtmfSender.insertDTMF')" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11 7 FAIL insertDTMF() should set toneBuffer to provided tones normalized, with old tones overridden promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: RTCDTMFSender" 8 FAIL insertDTMF() after remove and close should reject assert_throws: function "() => 9 dtmfSender.insertDTMF('123')" threw object "TypeError: undefined is not an object (evaluating 'dtmfSender.insertDTMF')" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11 2 PASS insertDTMF() should succeed if tones contains valid DTMF characters 3 PASS insertDTMF() should throw InvalidCharacterError if tones contains invalid DTMF characters 4 PASS insertDTMF() should throw InvalidStateError if transceiver is stopped 5 PASS insertDTMF() should throw InvalidStateError if transceiver.currentDirection is recvonly 6 PASS insertDTMF() should throw InvalidStateError if transceiver.currentDirection is inactive 7 PASS insertDTMF() should set toneBuffer to provided tones normalized, with old tones overridden 8 PASS insertDTMF() after remove and close should reject 10 9 -
trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange-long.https-expected.txt
r223327 r248282 1 1 2 FAIL insertDTMF with duration greater than 6000 should be clamped to 6000 assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 2 PASS insertDTMF with duration greater than 6000 should be clamped to 6000 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https-expected.txt
r237773 r248282 1 1 2 FAIL insertDTMF() with default duration and intertoneGap should fire tonechange events at the expected time assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 3 FAIL insertDTMF() with explicit duration and intertoneGap should fire tonechange events at the expected time assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 4 FAIL insertDTMF('') should not fire any tonechange event, including for '' tone assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 5 FAIL insertDTMF() with duration less than 40 should be clamped to 40 assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 6 FAIL insertDTMF() with interToneGap less than 30 should be clamped to 30 assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 7 FAIL insertDTMF with comma should delay next tonechange event for a constant 2000ms assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 8 FAIL insertDTMF() with transceiver stopped in the middle should stop future tonechange events from firing assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 9 FAIL Calling insertDTMF() in the middle of tonechange events should cause future tonechanges to be updated to new tones assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 10 FAIL Calling insertDTMF() multiple times in the middle of tonechange events should cause future tonechanges to be updated the last provided tones assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 11 FAIL Calling insertDTMF('') in the middle of tonechange events should stop future tonechange events from firing assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code 12 FAIL Setting transceiver.currentDirection to recvonly in the middle of tonechange events should stop future tonechange events from firing undefined is not an object (evaluating 'dtmfSender.addEventListener')13 FAIL Tone change event constructor works Can't find variable: RTCDTMFToneChangeEvent 14 FAIL Tone change event with unexpected name should not crash Can't find variable: RTCDTMFToneChangeEvent 2 PASS insertDTMF() with default duration and intertoneGap should fire tonechange events at the expected time 3 PASS insertDTMF() with explicit duration and intertoneGap should fire tonechange events at the expected time 4 PASS insertDTMF('') should not fire any tonechange event, including for '' tone 5 PASS insertDTMF() with duration less than 40 should be clamped to 40 6 PASS insertDTMF() with interToneGap less than 30 should be clamped to 30 7 PASS insertDTMF with comma should delay next tonechange event for a constant 2000ms 8 PASS insertDTMF() with transceiver stopped in the middle should stop future tonechange events from firing 9 PASS Calling insertDTMF() in the middle of tonechange events should cause future tonechanges to be updated to new tones 10 PASS Calling insertDTMF() multiple times in the middle of tonechange events should cause future tonechanges to be updated the last provided tones 11 PASS Calling insertDTMF('') in the middle of tonechange events should stop future tonechange events from firing 12 FAIL Setting transceiver.currentDirection to recvonly in the middle of tonechange events should stop future tonechange events from firing Cannot insert DTMF 13 PASS Tone change event constructor works 14 PASS Tone change event with unexpected name should not crash 15 15 -
trunk/Source/WebCore/ChangeLog
r248280 r248282 1 2019-08-05 Youenn Fablet <youenn@apple.com> 2 3 Support RTCRtpSender.dtmf 4 https://bugs.webkit.org/show_bug.cgi?id=200431 5 6 Reviewed by Eric Carlson. 7 8 Add a new backend interface to RTCDTMFSender and implementation of it using libwebrtc. 9 Update RTCDTMFSender to use that new backend and make RTCRtpSender return a RTCDTMFSender 10 conditionally on a newly added runtime flag. 11 Update RTCDTMFSender implementation based on https://w3c.github.io/webrtc-pc/#peer-to-peer-dtmf. 12 13 Covered by rebased tests. 14 15 * Modules/mediastream/PeerConnectionBackend.cpp: 16 (WebCore::PeerConnectionBackend::context const): 17 (WebCore::PeerConnectionBackend::transceiverFromSender): 18 * Modules/mediastream/PeerConnectionBackend.h: 19 * Modules/mediastream/RTCDTMFSender.cpp: 20 (WebCore::RTCDTMFSender::RTCDTMFSender): 21 (WebCore::RTCDTMFSender::canInsertDTMF const): 22 (WebCore::RTCDTMFSender::toneBuffer const): 23 (WebCore::isToneCharacterInvalid): 24 (WebCore::RTCDTMFSender::insertDTMF): 25 (WebCore::RTCDTMFSender::playNextTone): 26 (WebCore::RTCDTMFSender::onTonePlayed): 27 (WebCore::RTCDTMFSender::toneTimerFired): 28 (WebCore::RTCDTMFSender::stop): 29 (WebCore::RTCDTMFSender::activeDOMObjectName const): 30 (WebCore::RTCDTMFSender::canSuspendForDocumentSuspension const): 31 * Modules/mediastream/RTCDTMFSender.h: 32 * Modules/mediastream/RTCDTMFSender.idl: 33 * Modules/mediastream/RTCDTMFToneChangeEvent.cpp: 34 * Modules/mediastream/RTCDTMFToneChangeEvent.h: 35 * Modules/mediastream/RTCDTMFToneChangeEvent.idl: 36 * Modules/mediastream/RTCRtpSender.cpp: 37 (WebCore::RTCRtpSender::dtmf): 38 (WebCore::RTCRtpSender::currentTransceiverDirection const): 39 * Modules/mediastream/RTCRtpSender.h: 40 * Modules/mediastream/RTCRtpSender.idl: 41 * Modules/mediastream/RTCRtpSenderBackend.h: 42 * Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp: 43 (WebCore::LibWebRTCRtpSenderBackend::createDTMFBackend): 44 * Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h: 45 * Sources.txt: 46 * WebCore.xcodeproj/project.pbxproj: 47 * dom/EventNames.in: 48 * dom/EventTargetFactory.in: 49 * page/RuntimeEnabledFeatures.h: 50 (WebCore::RuntimeEnabledFeatures::webRTCDTMFEnabled const): 51 (WebCore::RuntimeEnabledFeatures::setWebRTCDTMFEnabled): 52 * platform/mediastream/RTCDTMFSenderBackend.h: Added. 53 * platform/mediastream/RTCDTMFSenderHandler.h: Removed. 54 * platform/mediastream/RTCDTMFSenderHandlerClient.h: Removed. 55 * platform/mediastream/libwebrtc/LibWebRTCDTMFSenderBackend.cpp: Added. 56 (WebCore::toWTFString): 57 (WebCore::LibWebRTCDTMFSenderBackend::LibWebRTCDTMFSenderBackend): 58 (WebCore::LibWebRTCDTMFSenderBackend::~LibWebRTCDTMFSenderBackend): 59 (WebCore::LibWebRTCDTMFSenderBackend::canInsertDTMF): 60 (WebCore::LibWebRTCDTMFSenderBackend::playTone): 61 (WebCore::LibWebRTCDTMFSenderBackend::tones const): 62 (WebCore::LibWebRTCDTMFSenderBackend::duration const): 63 (WebCore::LibWebRTCDTMFSenderBackend::interToneGap const): 64 (WebCore::LibWebRTCDTMFSenderBackend::OnToneChange): 65 (WebCore::LibWebRTCDTMFSenderBackend::onTonePlayed): 66 * platform/mediastream/libwebrtc/LibWebRTCDTMFSenderBackend.h: Added. 67 1 68 2019-08-05 Saam Barati <sbarati@apple.com> 2 69 -
trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp
r247430 r248282 562 562 } 563 563 564 ScriptExecutionContext* PeerConnectionBackend::context() const 565 { 566 return m_peerConnection.scriptExecutionContext(); 567 } 568 569 RTCRtpTransceiver* PeerConnectionBackend::transceiverFromSender(const RTCRtpSender& sender) 570 { 571 for (auto& transceiver : m_peerConnection.currentTransceivers()) { 572 if (&transceiver->sender() == &sender) 573 return transceiver.get(); 574 } 575 return nullptr; 576 } 577 564 578 #if !RELEASE_LOG_DISABLED 565 579 WTFLogChannel& PeerConnectionBackend::logChannel() const -
trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h
r244736 r248282 170 170 virtual void collectTransceivers() { }; 171 171 172 ScriptExecutionContext* context() const; 173 RTCRtpTransceiver* transceiverFromSender(const RTCRtpSender&); 174 172 175 protected: 173 176 void fireICECandidateEvent(RefPtr<RTCIceCandidate>&&, String&& url); -
trunk/Source/WebCore/Modules/mediastream/RTCDTMFSender.cpp
r243887 r248282 27 27 #include "RTCDTMFSender.h" 28 28 29 #if ENABLE(WEB_RTC _DTMF)29 #if ENABLE(WEB_RTC) 30 30 31 #include "MediaStreamTrack.h" 32 #include "RTCDTMFSenderHandler.h" 31 #include "RTCDTMFSenderBackend.h" 33 32 #include "RTCDTMFToneChangeEvent.h" 34 33 #include "ScriptExecutionContext.h" … … 39 38 WTF_MAKE_ISO_ALLOCATED_IMPL(RTCDTMFSender); 40 39 41 static const long minToneDurationMs = 40; 42 static const long defaultToneDurationMs = 100; 43 static const long maxToneDurationMs = 6000; 44 static const long minInterToneGapMs = 30; 45 static const long defaultInterToneGapMs = 70; 40 static const unsigned long minToneDurationMs = 40; 41 static const unsigned long maxToneDurationMs = 6000; 42 static const unsigned long minInterToneGapMs = 30; 46 43 47 RTCDTMFSender::RTCDTMFSender(ScriptExecutionContext& context, R efPtr<MediaStreamTrack>&& track)44 RTCDTMFSender::RTCDTMFSender(ScriptExecutionContext& context, RTCRtpSender& sender, std::unique_ptr<RTCDTMFSenderBackend>&& backend) 48 45 : ActiveDOMObject(&context) 49 , m_track(WTFMove(track)) 50 , m_duration(defaultToneDurationMs) 51 , m_interToneGap(defaultInterToneGapMs) 52 , m_stopped(false) 53 , m_scheduledEventTimer(*this, &RTCDTMFSender::scheduledEventTimerFired) 46 , m_toneTimer(*this, &RTCDTMFSender::toneTimerFired) 47 , m_sender(makeWeakPtr(sender)) 48 , m_backend(WTFMove(backend)) 54 49 { 50 m_backend->onTonePlayed([this](const String&) { 51 onTonePlayed(); 52 }); 53 suspendIfNeeded(); 55 54 } 56 55 … … 59 58 bool RTCDTMFSender::canInsertDTMF() const 60 59 { 61 return false;62 } 60 if (!m_sender || m_sender->isStopped()) 61 return false; 63 62 64 MediaStreamTrack* RTCDTMFSender::track() const 65 { 66 return m_track.get(); 63 auto currentDirection = m_sender->currentTransceiverDirection(); 64 if (!currentDirection) 65 return false; 66 if (*currentDirection != RTCRtpTransceiverDirection::Sendrecv && *currentDirection != RTCRtpTransceiverDirection::Sendonly) 67 return false; 68 69 return m_backend && m_backend->canInsertDTMF(); 67 70 } 68 71 69 72 String RTCDTMFSender::toneBuffer() const 70 73 { 74 return m_tones; 75 } 76 77 static inline bool isToneCharacterInvalid(UChar character) 78 { 79 if (character >= '0' && character <= '9') 80 return false; 81 if (character >= 'A' && character <= 'D') 82 return false; 83 return character != '#' && character != '*' && character != ','; 84 } 85 86 ExceptionOr<void> RTCDTMFSender::insertDTMF(const String& tones, size_t duration, size_t interToneGap) 87 { 88 if (!canInsertDTMF()) 89 return Exception { InvalidStateError, "Cannot insert DTMF"_s }; 90 91 auto normalizedTones = tones.convertToUppercaseWithoutLocale(); 92 if (normalizedTones.find(isToneCharacterInvalid) != notFound) 93 return Exception { InvalidCharacterError, "Tones are not valid"_s }; 94 95 m_tones = WTFMove(normalizedTones); 96 m_duration = clampTo(duration, minToneDurationMs, maxToneDurationMs); 97 m_interToneGap = std::max(interToneGap, minInterToneGapMs); 98 99 if (m_tones.isEmpty() || m_isPendingPlayoutTask) 100 return { }; 101 102 m_isPendingPlayoutTask = true; 103 scriptExecutionContext()->postTask([this, protectedThis = makeRef(*this)](auto&) { 104 playNextTone(); 105 }); 71 106 return { }; 72 107 } 73 108 74 ExceptionOr<void> RTCDTMFSender::insertDTMF(const String&, Optional<int> duration, Optional<int> interToneGap)109 void RTCDTMFSender::playNextTone() 75 110 { 76 if (!canInsertDTMF()) 77 return Exception { NotSupportedError }; 111 if (m_tones.isEmpty()) { 112 m_isPendingPlayoutTask = false; 113 dispatchEvent(RTCDTMFToneChangeEvent::create({ })); 114 return; 115 } 78 116 79 if (duration && (duration.value() > maxToneDurationMs || duration.value() < minToneDurationMs)) 80 return Exception { SyntaxError }; 117 if (!canInsertDTMF()) { 118 m_isPendingPlayoutTask = false; 119 return; 120 } 81 121 82 if (interToneGap && interToneGap.value() < minInterToneGapMs)83 return Exception { SyntaxError };122 auto currentTone = m_tones.substring(0, 1); 123 m_tones.remove(0); 84 124 85 m_duration = duration.valueOr(defaultToneDurationMs); 86 m_interToneGap = interToneGap.valueOr(defaultInterToneGapMs); 87 88 return Exception { SyntaxError }; 125 m_backend->playTone(currentTone, m_duration, m_interToneGap); 126 dispatchEvent(RTCDTMFToneChangeEvent::create(currentTone)); 89 127 } 90 128 91 void RTCDTMFSender:: didPlayTone(const String& tone)129 void RTCDTMFSender::onTonePlayed() 92 130 { 93 scheduleDispatchEvent(RTCDTMFToneChangeEvent::create(tone)); 131 m_toneTimer.startOneShot(1_ms * m_interToneGap); 132 } 133 134 void RTCDTMFSender::toneTimerFired() 135 { 136 playNextTone(); 94 137 } 95 138 96 139 void RTCDTMFSender::stop() 97 140 { 98 m_stopped = true; 141 m_backend = nullptr; 142 m_toneTimer.stop(); 99 143 } 100 144 … … 106 150 bool RTCDTMFSender::canSuspendForDocumentSuspension() const 107 151 { 108 // FIXME: We should try and do better here. 109 return false; 110 } 111 112 void RTCDTMFSender::scheduleDispatchEvent(Ref<Event>&& event) 113 { 114 m_scheduledEvents.append(WTFMove(event)); 115 116 if (!m_scheduledEventTimer.isActive()) 117 m_scheduledEventTimer.startOneShot(0_s); 118 } 119 120 void RTCDTMFSender::scheduledEventTimerFired() 121 { 122 if (m_stopped) 123 return; 124 125 Vector<Ref<Event>> events; 126 events.swap(m_scheduledEvents); 127 128 for (auto& event : events) 129 dispatchEvent(event); 152 return !m_sender || m_sender->isStopped(); 130 153 } 131 154 -
trunk/Source/WebCore/Modules/mediastream/RTCDTMFSender.h
r243887 r248282 26 26 #pragma once 27 27 28 #if ENABLE(WEB_RTC _DTMF)28 #if ENABLE(WEB_RTC) 29 29 30 30 #include "ActiveDOMObject.h" … … 37 37 38 38 class MediaStreamTrack; 39 class RTCDTMFSenderBackend; 40 class RTCRtpSender; 39 41 40 42 class RTCDTMFSender final : public RefCounted<RTCDTMFSender>, public EventTargetWithInlineData, public ActiveDOMObject { 41 43 WTF_MAKE_ISO_ALLOCATED(RTCDTMFSender); 42 44 public: 45 static Ref<RTCDTMFSender> create(ScriptExecutionContext& context, RTCRtpSender& sender, std::unique_ptr<RTCDTMFSenderBackend>&& backend) { return adoptRef(* new RTCDTMFSender(context, sender, WTFMove(backend))); } 43 46 virtual ~RTCDTMFSender(); 44 47 45 48 bool canInsertDTMF() const; 46 MediaStreamTrack* track() const;47 49 String toneBuffer() const; 48 int duration() const { return m_duration; }49 int interToneGap() const { return m_interToneGap; }50 50 51 ExceptionOr<void> insertDTMF(const String& tones, Optional<int> duration, Optional<int>interToneGap);51 ExceptionOr<void> insertDTMF(const String& tones, size_t duration, size_t interToneGap); 52 52 53 53 using RefCounted::ref; … … 55 55 56 56 private: 57 RTCDTMFSender(ScriptExecutionContext&, R efPtr<MediaStreamTrack>&&);57 RTCDTMFSender(ScriptExecutionContext&, RTCRtpSender&, std::unique_ptr<RTCDTMFSenderBackend>&&); 58 58 59 59 void stop() final; … … 67 67 void derefEventTarget() final { deref(); } 68 68 69 void didPlayTone(const String&);69 bool isStopped() const { return !m_sender; } 70 70 71 void scheduleDispatchEvent(Ref<Event>&&); 72 void scheduledEventTimerFired(); 71 void playNextTone(); 72 void onTonePlayed(); 73 void toneTimerFired(); 73 74 74 RefPtr<MediaStreamTrack> m_track; 75 int m_duration; 76 int m_interToneGap; 77 78 bool m_stopped; 79 80 Timer m_scheduledEventTimer; 81 Vector<Ref<Event>> m_scheduledEvents; 75 Timer m_toneTimer; 76 WeakPtr<RTCRtpSender> m_sender; 77 std::unique_ptr<RTCDTMFSenderBackend> m_backend; 78 String m_tones; 79 size_t m_duration; 80 size_t m_interToneGap; 81 bool m_isPendingPlayoutTask { false }; 82 82 }; 83 83 -
trunk/Source/WebCore/Modules/mediastream/RTCDTMFSender.idl
r217194 r248282 27 27 [ 28 28 ActiveDOMObject, 29 Conditional=WEB_RTC _DTMF,29 Conditional=WEB_RTC, 30 30 EnabledAtRuntime=PeerConnection, 31 31 ] interface RTCDTMFSender : EventTarget { 32 // FIXME 169662: change to unsigned long with defaults 33 [MayThrowException] void insertDTMF(DOMString tones, optional long duration, optional long interToneGap); 32 [MayThrowException] void insertDTMF(DOMString tones, optional unsigned long duration = 100, optional unsigned long interToneGap = 70); 34 33 attribute EventHandler ontonechange; 34 35 readonly attribute boolean canInsertDTMF; 35 36 readonly attribute DOMString toneBuffer; 36 37 // Legacy38 // FIXME 169662: remove39 readonly attribute boolean canInsertDTMF;40 // FIXME 169662: remove41 readonly attribute MediaStreamTrack track;42 // FIXME 169662: remove43 readonly attribute long duration;44 // FIXME 169662: remove45 readonly attribute long interToneGap;46 37 }; -
trunk/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.cpp
r246490 r248282 27 27 #include "RTCDTMFToneChangeEvent.h" 28 28 29 #if ENABLE(WEB_RTC _DTMF)29 #if ENABLE(WEB_RTC) 30 30 31 31 #include "EventNames.h" -
trunk/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.h
r246490 r248282 26 26 #pragma once 27 27 28 #if ENABLE(WEB_RTC _DTMF)28 #if ENABLE(WEB_RTC) 29 29 30 30 #include "Event.h" -
trunk/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.idl
r214536 r248282 26 26 27 27 [ 28 Conditional=WEB_RTC _DTMF,28 Conditional=WEB_RTC, 29 29 Constructor(DOMString type, optional RTCDTMFToneChangeEventInit eventInitDict), 30 30 EnabledAtRuntime=PeerConnection, … … 34 34 35 35 [ 36 Conditional=WEB_RTC _DTMF,36 Conditional=WEB_RTC, 37 37 EnabledAtRuntime=PeerConnection 38 38 ] dictionary RTCDTMFToneChangeEventInit : EventInit { 39 requiredDOMString tone;39 DOMString tone; 40 40 }; -
trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp
r243887 r248282 34 34 #if ENABLE(WEB_RTC) 35 35 36 #include "RTCDTMFSender.h" 37 #include "RTCDTMFSenderBackend.h" 36 38 #include "RTCRtpCapabilities.h" 37 39 #include "RuntimeEnabledFeatures.h" … … 62 64 ASSERT(!RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled() || m_backend); 63 65 } 66 67 RTCRtpSender::~RTCRtpSender() = default; 64 68 65 69 void RTCRtpSender::setTrackToNull() … … 136 140 } 137 141 142 RTCDTMFSender* RTCRtpSender::dtmf() 143 { 144 if (!m_dtmfSender && m_connection && m_connection->context() && m_backend) 145 m_dtmfSender = RTCDTMFSender::create(*m_connection->context(), *this, m_backend->createDTMFBackend()); 146 147 return m_dtmfSender.get(); 148 } 149 150 Optional<RTCRtpTransceiverDirection> RTCRtpSender::currentTransceiverDirection() const 151 { 152 if (!m_connection) 153 return { }; 154 155 auto* transceiver = m_connection->transceiverFromSender(*this); 156 if (!transceiver) 157 return { }; 158 159 return transceiver->currentDirection(); 160 } 161 138 162 } // namespace WebCore 139 163 -
trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.h
r243887 r248282 36 36 #include "PeerConnectionBackend.h" 37 37 #include "RTCRtpSenderBackend.h" 38 #include "RTCRtpTransceiverDirection.h" 38 39 #include "ScriptWrappable.h" 40 #include <wtf/WeakPtr.h> 39 41 40 42 namespace WebCore { 41 43 42 44 class PeerConnectionBackend; 45 class RTCDTMFSender; 43 46 struct RTCRtpCapabilities; 44 47 45 class RTCRtpSender final : public RefCounted<RTCRtpSender>, public ScriptWrappable {48 class RTCRtpSender final : public RefCounted<RTCRtpSender>, public ScriptWrappable, public CanMakeWeakPtr<RTCRtpSender> { 46 49 WTF_MAKE_ISO_ALLOCATED(RTCRtpSender); 47 50 public: 48 51 static Ref<RTCRtpSender> create(PeerConnectionBackend&, Ref<MediaStreamTrack>&&, Vector<String>&& mediaStreamIds, std::unique_ptr<RTCRtpSenderBackend>&&); 49 52 static Ref<RTCRtpSender> create(PeerConnectionBackend&, String&& trackKind, Vector<String>&& mediaStreamIds, std::unique_ptr<RTCRtpSenderBackend>&&); 53 ~RTCRtpSender(); 50 54 51 55 static Optional<RTCRtpCapabilities> getCapabilities(ScriptExecutionContext&, const String& kind); … … 75 79 bool isCreatedBy(const PeerConnectionBackend&) const; 76 80 81 RTCDTMFSender* dtmf(); 82 Optional<RTCRtpTransceiverDirection> currentTransceiverDirection() const; 83 77 84 private: 78 85 RTCRtpSender(PeerConnectionBackend&, String&& trackKind, Vector<String>&& mediaStreamIds, std::unique_ptr<RTCRtpSenderBackend>&&); … … 84 91 std::unique_ptr<RTCRtpSenderBackend> m_backend; 85 92 WeakPtr<PeerConnectionBackend> m_connection; 93 RefPtr<RTCDTMFSender> m_dtmfSender; 86 94 }; 87 95 -
trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.idl
r237911 r248282 44 44 [CallWith=ScriptExecutionContext] Promise<void> replaceTrack(MediaStreamTrack? withTrack); 45 45 Promise<RTCStatsReport> getStats(); 46 47 [Conditional=WEB_RTC, EnabledAtRuntime=WebRTCDTMF] readonly attribute RTCDTMFSender? dtmf; 46 48 }; -
trunk/Source/WebCore/Modules/mediastream/RTCRtpSenderBackend.h
r235973 r248282 32 32 33 33 class MediaStreamTrack; 34 class RTCDTMFSenderBackend; 34 35 class RTCRtpSender; 35 36 struct RTCRtpSendParameters; … … 41 42 virtual RTCRtpSendParameters getParameters() const = 0; 42 43 virtual void setParameters(const RTCRtpSendParameters&, DOMPromiseDeferred<void>&&) = 0; 44 virtual std::unique_ptr<RTCDTMFSenderBackend> createDTMFBackend() = 0; 43 45 virtual ~RTCRtpSenderBackend() = default; 44 46 }; -
trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp
r239427 r248282 28 28 #if ENABLE(WEB_RTC) && USE(LIBWEBRTC) 29 29 30 #include "LibWebRTCDTMFSenderBackend.h" 30 31 #include "LibWebRTCPeerConnectionBackend.h" 31 32 #include "LibWebRTCUtils.h" … … 146 147 } 147 148 149 std::unique_ptr<RTCDTMFSenderBackend> LibWebRTCRtpSenderBackend::createDTMFBackend() 150 { 151 return std::make_unique<LibWebRTCDTMFSenderBackend>(m_rtcSender->GetDtmfSender()); 152 } 153 148 154 } // namespace WebCore 149 155 -
trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h
r241183 r248282 112 112 RTCRtpSendParameters getParameters() const final; 113 113 void setParameters(const RTCRtpSendParameters&, DOMPromiseDeferred<void>&&) final; 114 std::unique_ptr<RTCDTMFSenderBackend> createDTMFBackend() final; 114 115 115 116 WeakPtr<LibWebRTCPeerConnectionBackend> m_peerConnectionBackend; -
trunk/Source/WebCore/Sources.txt
r248200 r248282 1932 1932 1933 1933 platform/mediastream/libwebrtc/LibWebRTCProvider.cpp 1934 platform/mediastream/libwebrtc/LibWebRTCDTMFSenderBackend.cpp 1934 1935 1935 1936 platform/mock/DeviceOrientationClientMock.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r248266 r248282 167 167 078E093C17D16E1C00420AA1 /* RTCDataChannelHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BA217CF0AD400848E51 /* RTCDataChannelHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 168 168 078E093D17D16E1C00420AA1 /* RTCDataChannelHandlerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BA317CF0AD400848E51 /* RTCDataChannelHandlerClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 169 078E093E17D16E1C00420AA1 /* RTCDTMFSenderHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BA417CF0AD400848E51 /* RTCDTMFSenderHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };170 078E093F17D16E1C00420AA1 /* RTCDTMFSenderHandlerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BA517CF0AD400848E51 /* RTCDTMFSenderHandlerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };171 169 078E094017D16E1C00420AA1 /* RTCIceCandidateDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BA717CF0AD400848E51 /* RTCIceCandidateDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; }; 172 170 078E094217D16E1C00420AA1 /* RTCPeerConnectionHandlerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BAA17CF0AD400848E51 /* RTCPeerConnectionHandlerClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 5315 5313 07221BA217CF0AD400848E51 /* RTCDataChannelHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDataChannelHandler.h; sourceTree = "<group>"; }; 5316 5314 07221BA317CF0AD400848E51 /* RTCDataChannelHandlerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDataChannelHandlerClient.h; sourceTree = "<group>"; }; 5317 07221BA417CF0AD400848E51 /* RTCDTMFSenderHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDTMFSenderHandler.h; sourceTree = "<group>"; };5318 07221BA517CF0AD400848E51 /* RTCDTMFSenderHandlerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDTMFSenderHandlerClient.h; sourceTree = "<group>"; };5319 5315 07221BA617CF0AD400848E51 /* RTCIceCandidateDescriptor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCIceCandidateDescriptor.cpp; sourceTree = "<group>"; }; 5320 5316 07221BA717CF0AD400848E51 /* RTCIceCandidateDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCIceCandidateDescriptor.h; sourceTree = "<group>"; }; … … 7393 7389 41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptCachedFrameData.h; sourceTree = "<group>"; }; 7394 7390 41F1D21E0EF35C2A00DA8753 /* ScriptCachedFrameData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptCachedFrameData.cpp; sourceTree = "<group>"; }; 7391 41F2354422F5503300B4FCDB /* RTCDTMFSenderBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDTMFSenderBackend.h; sourceTree = "<group>"; }; 7392 41F2354522F550BE00B4FCDB /* LibWebRTCDTMFSenderBackend.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibWebRTCDTMFSenderBackend.cpp; path = libwebrtc/LibWebRTCDTMFSenderBackend.cpp; sourceTree = "<group>"; }; 7393 41F2354622F550BF00B4FCDB /* LibWebRTCDTMFSenderBackend.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LibWebRTCDTMFSenderBackend.h; path = libwebrtc/LibWebRTCDTMFSenderBackend.h; sourceTree = "<group>"; }; 7395 7394 41F54F7D1C50C4F600338488 /* FetchBody.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FetchBody.cpp; sourceTree = "<group>"; }; 7396 7395 41F54F7E1C50C4F600338488 /* FetchBody.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchBody.h; sourceTree = "<group>"; }; … … 15846 15845 07221BA317CF0AD400848E51 /* RTCDataChannelHandlerClient.h */, 15847 15846 316DE7011E83AE1D0084C261 /* RTCDataChannelState.h */, 15848 07221BA417CF0AD400848E51 /* RTCDTMFSenderHandler.h */, 15849 07221BA517CF0AD400848E51 /* RTCDTMFSenderHandlerClient.h */, 15847 41F2354422F5503300B4FCDB /* RTCDTMFSenderBackend.h */, 15850 15848 07221BA617CF0AD400848E51 /* RTCIceCandidateDescriptor.cpp */, 15851 15849 07221BA717CF0AD400848E51 /* RTCIceCandidateDescriptor.h */, … … 17659 17657 415080341E3F00AA0051D75D /* LibWebRTCAudioModule.cpp */, 17660 17658 415080351E3F00AA0051D75D /* LibWebRTCAudioModule.h */, 17659 41F2354522F550BE00B4FCDB /* LibWebRTCDTMFSenderBackend.cpp */, 17660 41F2354622F550BF00B4FCDB /* LibWebRTCDTMFSenderBackend.h */, 17661 17661 415747431E38699E00E914D8 /* LibWebRTCMacros.h */, 17662 17662 41A1B00D1E52656E007F3769 /* LibWebRTCProvider.cpp */, … … 31326 31326 316DE7021E83AE1D0084C261 /* RTCDataChannelState.h in Headers */, 31327 31327 078E092017D14D1C00420AA1 /* RTCDTMFSender.h in Headers */, 31328 078E093E17D16E1C00420AA1 /* RTCDTMFSenderHandler.h in Headers */,31329 078E093F17D16E1C00420AA1 /* RTCDTMFSenderHandlerClient.h in Headers */,31330 31328 078E092117D14D1C00420AA1 /* RTCDTMFToneChangeEvent.h in Headers */, 31331 31329 078E092317D14D1C00420AA1 /* RTCIceCandidate.h in Headers */, -
trunk/Source/WebCore/dom/EventNames.in
r244582 r248282 57 57 RTCPeerConnectionIceEvent conditional=WEB_RTC 58 58 RTCDataChannelEvent conditional=WEB_RTC 59 RTCDTMFToneChangeEvent conditional=WEB_RTC _DTMF59 RTCDTMFToneChangeEvent conditional=WEB_RTC 60 60 RTCPeerConnectionIceEvent conditional=WEB_RTC 61 61 RTCTrackEvent conditional=WEB_RTC -
trunk/Source/WebCore/dom/EventTargetFactory.in
r237766 r248282 34 34 Performance 35 35 RTCDataChannel conditional=WEB_RTC 36 RTCDTMFSender conditional=WEB_RTC _DTMF36 RTCDTMFSender conditional=WEB_RTC 37 37 RTCPeerConnection conditional=WEB_RTC 38 38 ServiceWorker conditional=SERVICE_WORKER -
trunk/Source/WebCore/page/RuntimeEnabledFeatures.h
r247527 r248282 224 224 225 225 #if ENABLE(WEB_RTC) 226 bool webRTCDTMFEnabled() const { return m_isWebRTCDTMFEnabled; } 227 void setWebRTCDTMFEnabled(bool isEnabled) { m_isWebRTCDTMFEnabled = isEnabled; } 226 228 bool webRTCVP8CodecEnabled() const { return m_isWebRTCVP8CodecEnabled; } 227 229 void setWebRTCVP8CodecEnabled(bool isEnabled) { m_isWebRTCVP8CodecEnabled = isEnabled; } … … 449 451 450 452 #if ENABLE(WEB_RTC) 453 bool m_isWebRTCDTMFEnabled { true }; 451 454 bool m_isWebRTCVP8CodecEnabled { true }; 452 455 bool m_isWebRTCUnifiedPlanEnabled { true }; -
trunk/Source/WebCore/platform/mediastream/RTCDTMFSenderBackend.h
r248281 r248282 1 1 /* 2 * Copyright (C) 201 8Apple Inc.2 * Copyright (C) 2019 Apple Inc. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #if ENABLE(WEB_RTC) 28 28 29 #include "JSDOMPromiseDeferred.h" 29 #include "ExceptionOr.h" 30 #include <wtf/Function.h> 31 #include <wtf/text/WTFString.h> 30 32 31 33 namespace WebCore { 32 34 33 class MediaStreamTrack; 34 class RTCRtpSender; 35 struct RTCRtpSendParameters; 36 class ScriptExecutionContext; 35 class RTCDTMFSenderBackend { 36 public: 37 virtual bool canInsertDTMF() = 0; 38 virtual void playTone(const String& tone, size_t duration, size_t interToneGap) = 0; 39 virtual void onTonePlayed(Function<void(const String&)>&&) = 0; 37 40 38 class RTCRtpSenderBackend { 39 public: 40 virtual void replaceTrack(ScriptExecutionContext&, RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&) = 0; 41 virtual RTCRtpSendParameters getParameters() const = 0; 42 virtual void setParameters(const RTCRtpSendParameters&, DOMPromiseDeferred<void>&&) = 0; 43 virtual ~RTCRtpSenderBackend() = default; 41 virtual String tones() const = 0; 42 virtual size_t duration() const = 0; 43 virtual size_t interToneGap() const = 0; 44 45 virtual ~RTCDTMFSenderBackend() = default; 44 46 }; 45 47 -
trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCDTMFSenderBackend.h
r248281 r248282 1 1 /* 2 * Copyright (C) 201 8Apple Inc.2 * Copyright (C) 2019 Apple Inc. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #if ENABLE(WEB_RTC) 28 28 29 #include "JSDOMPromiseDeferred.h" 29 #include "LibWebRTCMacros.h" 30 #include "RTCDTMFSenderBackend.h" 31 #include <wtf/WeakPtr.h> 32 33 ALLOW_UNUSED_PARAMETERS_BEGIN 34 35 #include <webrtc/api/dtmfsenderinterface.h> 36 #include <webrtc/rtc_base/scoped_ref_ptr.h> 37 38 ALLOW_UNUSED_PARAMETERS_END 30 39 31 40 namespace WebCore { 32 41 33 class MediaStreamTrack;34 class RTCRtpSender; 35 struct RTCRtpSendParameters;36 class ScriptExecutionContext;42 class LibWebRTCDTMFSenderBackend final : public RTCDTMFSenderBackend, private webrtc::DtmfSenderObserverInterface, public CanMakeWeakPtr<LibWebRTCDTMFSenderBackend> { 43 public: 44 explicit LibWebRTCDTMFSenderBackend(rtc::scoped_refptr<webrtc::DtmfSenderInterface>&&); 45 ~LibWebRTCDTMFSenderBackend(); 37 46 38 class RTCRtpSenderBackend { 39 public: 40 virtual void replaceTrack(ScriptExecutionContext&, RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&) = 0; 41 virtual RTCRtpSendParameters getParameters() const = 0; 42 virtual void setParameters(const RTCRtpSendParameters&, DOMPromiseDeferred<void>&&) = 0; 43 virtual ~RTCRtpSenderBackend() = default; 47 private: 48 // RTCDTMFSenderBackend 49 bool canInsertDTMF() final; 50 void playTone(const String& tone, size_t duration, size_t interToneGap) final; 51 void onTonePlayed(Function<void(const String&)>&&) final; 52 String tones() const final; 53 size_t duration() const final; 54 size_t interToneGap() const final; 55 56 // DtmfSenderObserverInterface 57 void OnToneChange(const std::string& tone, const std::string&) final; 58 59 rtc::scoped_refptr<webrtc::DtmfSenderInterface> m_sender; 60 Function<void(const String&)> m_onTonePlayed; 61 WeakPtr<LibWebRTCDTMFSenderBackend> m_weakThis; 44 62 }; 45 63 -
trunk/Source/WebKit/ChangeLog
r248281 r248282 1 2019-08-05 Youenn Fablet <youenn@apple.com> 2 3 Support RTCRtpSender.dtmf 4 https://bugs.webkit.org/show_bug.cgi?id=200431 5 6 Reviewed by Eric Carlson. 7 8 * Shared/WebPreferences.yaml: 9 1 10 2019-08-05 Simon Fraser <simon.fraser@apple.com> 2 11 -
trunk/Source/WebKit/Shared/WebPreferences.yaml
r247527 r248282 573 573 category: experimental 574 574 575 WebRTCDTMFEnabled: 576 type: bool 577 defaultValue: true 578 webcoreBinding: RuntimeEnabledFeatures 579 condition: ENABLE(WEB_RTC) 580 humanReadableName: "WebRTC DTMF" 581 humanReadableDescription: "Enable WebRTC DTMF" 582 category: experimental 583 575 584 WebRTCH264SimulcastEnabled: 576 585 type: bool
Note:
See TracChangeset
for help on using the changeset viewer.