Bug 1425901: Use nsITimerCallback for DTMF timers. r?drno
MozReview-Commit-ID: 2IlDknNhlAG
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -2327,18 +2327,18 @@ PeerConnectionImpl::RemoveTrack(MediaStr
mMedia->GetTransceivers();
nsresult rv = NS_ERROR_INVALID_ARG;
for (RefPtr<TransceiverImpl>& transceiver : transceivers) {
if (transceiver->HasSendTrack(&aTrack)) {
// TODO(bug 1401983): Move DTMF stuff to TransceiverImpl
for (size_t i = 0; i < mDTMFStates.Length(); ++i) {
- if (mDTMFStates[i].mTransceiver.get() == transceiver.get()) {
- mDTMFStates[i].mSendTimer->Cancel();
+ if (mDTMFStates[i]->mTransceiver.get() == transceiver.get()) {
+ mDTMFStates[i]->mSendTimer->Cancel();
mDTMFStates.RemoveElementAt(i);
break;
}
}
rv = transceiver->UpdateSendTrack(nullptr);
break;
}
@@ -2430,40 +2430,38 @@ PeerConnectionImpl::InsertDTMF(Transceiv
MOZ_ASSERT(duration >= 40, "duration must be at least 40");
MOZ_ASSERT(duration <= 6000, "duration must be at most 6000");
MOZ_ASSERT(interToneGap >= 30, "interToneGap must be at least 30");
JSErrorResult jrv;
// TODO(bug 1401983): Move DTMF stuff to TransceiverImpl
// Attempt to locate state for the DTMFSender
- DTMFState* state = nullptr;
+ RefPtr<DTMFState> state;
for (auto& dtmfState : mDTMFStates) {
- if (dtmfState.mTransceiver.get() == &transceiver) {
- state = &dtmfState;
+ if (dtmfState->mTransceiver.get() == &transceiver) {
+ state = dtmfState;
break;
}
}
// No state yet, create a new one
if (!state) {
- state = mDTMFStates.AppendElement();
+ state = *mDTMFStates.AppendElement(new DTMFState);
state->mPCObserver = mPCObserver;
state->mTransceiver = &transceiver;
state->mSendTimer = NS_NewTimer();
}
MOZ_ASSERT(state);
state->mTones = tones;
state->mDuration = duration;
state->mInterToneGap = interToneGap;
if (!state->mTones.IsEmpty()) {
- state->mSendTimer->InitWithNamedFuncCallback(DTMFSendTimerCallback_m, state, 0,
- nsITimer::TYPE_ONE_SHOT,
- "DTMFSendTimerCallback_m");
+ state->mSendTimer->InitWithCallback(state, 0, nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
}
NS_IMETHODIMP
PeerConnectionImpl::GetDTMFToneBuffer(mozilla::dom::RTCRtpSender& sender,
nsAString& outToneBuffer) {
@@ -2476,18 +2474,18 @@ PeerConnectionImpl::GetDTMFToneBuffer(mo
if (jrv.Failed()) {
NS_WARNING("Failed to retrieve track for RTCRtpSender!");
return jrv.StealNSResult();
}
// TODO(bug 1401983): Move DTMF stuff to TransceiverImpl
// Attempt to locate state for the DTMFSender
for (auto& dtmfState : mDTMFStates) {
- if (dtmfState.mTransceiver->HasSendTrack(mst)) {
- outToneBuffer = dtmfState.mTones;
+ if (dtmfState->mTransceiver->HasSendTrack(mst)) {
+ outToneBuffer = dtmfState->mTones;
break;
}
}
return NS_OK;
}
NS_IMETHODIMP
@@ -2505,18 +2503,18 @@ PeerConnectionImpl::ReplaceTrackNoRenego
if (NS_FAILED(rv)) {
CSFLogError(LOGTAG,
"Failed to update transceiver: %d", static_cast<int>(rv));
return rv;
}
// TODO(bug 1401983): Move DTMF stuff to TransceiverImpl
for (size_t i = 0; i < mDTMFStates.Length(); ++i) {
- if (mDTMFStates[i].mTransceiver.get() == &aTransceiver) {
- mDTMFStates[i].mSendTimer->Cancel();
+ if (mDTMFStates[i]->mTransceiver.get() == &aTransceiver) {
+ mDTMFStates[i]->mSendTimer->Cancel();
mDTMFStates.RemoveElementAt(i);
break;
}
}
if (aWithTrack) {
aWithTrack->AddPrincipalChangeObserver(this);
PrincipalChanged(aWithTrack);
@@ -2795,17 +2793,17 @@ PeerConnectionImpl::RecordEndOfCallTelem
nsresult
PeerConnectionImpl::CloseInt()
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
// TODO(bug 1401983): Move DTMF stuff to TransceiverImpl
for (auto& dtmfState : mDTMFStates) {
- dtmfState.mSendTimer->Cancel();
+ dtmfState->mSendTimer->Cancel();
}
// We do this at the end of the call because we want to make sure we've waited
// for all trickle ICE candidates to come in; this can happen well after we've
// transitioned to connected. As a bonus, this allows us to detect race
// conditions where a stats dispatch happens right as the PC closes.
if (!mPrivateWindow) {
RecordLongtermICEStatistics();
@@ -3772,60 +3770,58 @@ PeerConnectionImpl::startCallTelem() {
// Start time for calls
mStartTime = TimeStamp::Now();
// Increment session call counter
// If we want to track Loop calls independently here, we need two histograms.
Telemetry::Accumulate(Telemetry::WEBRTC_CALL_COUNT_2, 1);
}
-void
-PeerConnectionImpl::DTMFSendTimerCallback_m(nsITimer* timer, void* closure)
+nsresult
+PeerConnectionImpl::DTMFState::Notify(nsITimer* timer)
{
MOZ_ASSERT(NS_IsMainThread());
- auto state = static_cast<DTMFState*>(closure);
-
nsString eventTone;
- if (!state->mTones.IsEmpty()) {
- uint16_t toneChar = state->mTones.CharAt(0);
+ if (!mTones.IsEmpty()) {
+ uint16_t toneChar = mTones.CharAt(0);
int tone = GetDTMFToneCode(toneChar);
eventTone.Assign(toneChar);
- state->mTones.Cut(0, 1);
+ mTones.Cut(0, 1);
if (tone == -1) {
- state->mSendTimer->InitWithNamedFuncCallback(DTMFSendTimerCallback_m, state,
- 2000, nsITimer::TYPE_ONE_SHOT,
- "DTMFSendTimerCallback_m");
+ mSendTimer->InitWithCallback(this, 2000, nsITimer::TYPE_ONE_SHOT);
} else {
// Reset delay if necessary
- state->mSendTimer->InitWithNamedFuncCallback(DTMFSendTimerCallback_m, state,
- state->mDuration + state->mInterToneGap,
- nsITimer::TYPE_ONE_SHOT,
- "DTMFSendTimerCallback_m");
-
- state->mTransceiver->InsertDTMFTone(tone, state->mDuration);
+ mSendTimer->InitWithCallback(this,
+ mDuration + mInterToneGap,
+ nsITimer::TYPE_ONE_SHOT);
+
+ mTransceiver->InsertDTMFTone(tone, mDuration);
}
} else {
- state->mSendTimer->Cancel();
+ mSendTimer->Cancel();
}
- RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(state->mPCObserver);
+ RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
if (!pco) {
NS_WARNING("Failed to dispatch the RTCDTMFToneChange event!");
- return;
+ return NS_OK; // Return is ignored anyhow
}
JSErrorResult jrv;
- pco->OnDTMFToneChange(*state->mTransceiver->GetSendTrack(), eventTone, jrv);
+ pco->OnDTMFToneChange(*mTransceiver->GetSendTrack(), eventTone, jrv);
if (jrv.Failed()) {
NS_WARNING("Failed to dispatch the RTCDTMFToneChange event!");
- return;
}
+
+ return NS_OK;
}
PeerConnectionImpl::DTMFState::DTMFState() = default;
PeerConnectionImpl::DTMFState::~DTMFState() = default;
+NS_IMPL_ISUPPORTS(PeerConnectionImpl::DTMFState, nsITimerCallback)
+
} // end mozilla namespace
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -822,32 +822,34 @@ private:
// Whether this PeerConnection is being counted as active by mWindow
bool mActiveOnWindow;
// storage for Telemetry data
uint16_t mMaxReceiving[SdpMediaSection::kMediaTypes];
uint16_t mMaxSending[SdpMediaSection::kMediaTypes];
// DTMF
- struct DTMFState {
- DTMFState();
- ~DTMFState();
- nsWeakPtr mPCObserver;
- RefPtr<TransceiverImpl> mTransceiver;
- nsCOMPtr<nsITimer> mSendTimer;
- nsString mTones;
- uint32_t mDuration;
- uint32_t mInterToneGap;
+ class DTMFState : public nsITimerCallback {
+ virtual ~DTMFState();
+ public:
+ DTMFState();
+
+ NS_DECL_NSITIMERCALLBACK
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ nsWeakPtr mPCObserver;
+ RefPtr<TransceiverImpl> mTransceiver;
+ nsCOMPtr<nsITimer> mSendTimer;
+ nsString mTones;
+ uint32_t mDuration;
+ uint32_t mInterToneGap;
};
- static void
- DTMFSendTimerCallback_m(nsITimer* timer, void*);
-
// TODO(bug 1401983): Move DTMF stuff to TransceiverImpl
- nsTArray<DTMFState> mDTMFStates;
+ nsTArray<RefPtr<DTMFState>> mDTMFStates;
std::vector<unsigned> mSendPacketDumpFlags;
std::vector<unsigned> mRecvPacketDumpFlags;
Atomic<bool> mPacketDumpEnabled;
mutable Mutex mPacketDumpFlagsMutex;
public:
//these are temporary until the DataChannel Listen/Connect API is removed