Bug 1425901: Use nsITimerCallback for DTMF timers. r=drno
authorByron Campen [:bwc] <docfaraday@gmail.com>
Mon, 18 Dec 2017 12:36:23 -0600
changeset 448622 c74685e570c20efe8f3d36355a7c5c30540aabac
parent 448621 9723654fda3997e90b1c1b2eed5df324c9457c6b
child 448623 ff1a826ff6095b925662bbde44956a94d0757a5e
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrno
bugs1425901
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1425901: Use nsITimerCallback for DTMF timers. r=drno MozReview-Commit-ID: 2IlDknNhlAG
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -2331,18 +2331,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;
     }
@@ -2434,40 +2434,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) {
@@ -2480,18 +2478,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
@@ -2509,18 +2507,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);
@@ -2799,17 +2797,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();
@@ -3793,60 +3791,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;
 
   // used to store the raw trickle candidate string for display
   // on the about:webrtc raw candidates table.