diff --git a/api/dtmfsenderinterface.h b/api/dtmfsenderinterface.h index b79bb31804..d8714f5d29 100644 --- a/api/dtmfsenderinterface.h +++ b/api/dtmfsenderinterface.h @@ -26,7 +26,14 @@ class DtmfSenderObserverInterface { // Triggered when DTMF |tone| is sent. // If |tone| is empty that means the DtmfSender has sent out all the given // tones. - virtual void OnToneChange(const std::string& tone) = 0; + // The callback includes the state of the tone buffer at the time when + // the tone finished playing. + virtual void OnToneChange(const std::string& tone, + const std::string& tone_buffer) {} + // DEPRECATED: Older API without tone buffer. + // TODO(bugs.webrtc.org/9725): Remove old API and default implementation + // when old callers are gone. + virtual void OnToneChange(const std::string& tone) {} protected: virtual ~DtmfSenderObserverInterface() = default; diff --git a/pc/dtmfsender.cc b/pc/dtmfsender.cc index e80ad6e615..8a17b031b7 100644 --- a/pc/dtmfsender.cc +++ b/pc/dtmfsender.cc @@ -166,6 +166,7 @@ void DtmfSender::DoInsertDtmf() { tones_.clear(); // Fire a “OnToneChange” event with an empty string and stop. if (observer_) { + observer_->OnToneChange(std::string(), tones_); observer_->OnToneChange(std::string()); } return; @@ -200,6 +201,8 @@ void DtmfSender::DoInsertDtmf() { // Fire a “OnToneChange” event with the tone that's just processed. if (observer_) { + observer_->OnToneChange(tones_.substr(first_tone_pos, 1), + tones_.substr(first_tone_pos + 1)); observer_->OnToneChange(tones_.substr(first_tone_pos, 1)); } diff --git a/pc/dtmfsender_unittest.cc b/pc/dtmfsender_unittest.cc index dc8cc115b8..ce0f2d17ee 100644 --- a/pc/dtmfsender_unittest.cc +++ b/pc/dtmfsender_unittest.cc @@ -34,7 +34,15 @@ class FakeDtmfObserver : public DtmfSenderObserverInterface { // Implements DtmfSenderObserverInterface. void OnToneChange(const std::string& tone) override { + tones_from_single_argument_callback_.push_back(tone); + if (tone.empty()) { + completed_ = true; + } + } + void OnToneChange(const std::string& tone, + const std::string& tone_buffer) override { tones_.push_back(tone); + tones_remaining_ = tone_buffer; if (tone.empty()) { completed_ = true; } @@ -42,10 +50,16 @@ class FakeDtmfObserver : public DtmfSenderObserverInterface { // getters const std::vector& tones() const { return tones_; } + const std::vector& tones_from_single_argument_callback() const { + return tones_from_single_argument_callback_; + } + const std::string tones_remaining() { return tones_remaining_; } bool completed() const { return completed_; } private: std::vector tones_; + std::vector tones_from_single_argument_callback_; + std::string tones_remaining_; bool completed_; }; @@ -181,7 +195,10 @@ class DtmfSenderTest : public testing::Test { const std::vector& tones = observer_->tones(); // The observer will get an empty string at the end. EXPECT_EQ(tones_ref.size() + 1, tones.size()); + EXPECT_EQ(observer_->tones(), + observer_->tones_from_single_argument_callback()); EXPECT_TRUE(tones.back().empty()); + EXPECT_TRUE(observer_->tones_remaining().empty()); std::string::const_iterator it_ref = tones_ref.begin(); std::vector::const_iterator it = tones.begin(); while (it_ref != tones_ref.end() && it != tones.end()) {