void
PeerConnectionMedia::RollbackIceRestart_s()
{
  ASSERT_ON_THREAD(mSTSThread);

  // hold the restart context so we can disconnect signals
  RefPtr<NrIceCtx> restartCtx = mIceCtxHdlr->ctx();

  // restore old streams since we're rolling back
  for (auto& transportFlow : mTransportFlows) {
    RefPtr<TransportFlow> aFlow = transportFlow.second;
    if (!aFlow) continue;
    TransportLayerIce* ice =
      static_cast<TransportLayerIce*>(aFlow->GetLayer(TransportLayerIce::ID()));
    ice->RestoreOldStream();
  }

  mIceCtxHdlr->RollbackIceRestart();
  ConnectSignals(mIceCtxHdlr->ctx().get(), restartCtx.get());

  // Fixup the telemetry by transferring abandoned ctx stats to current ctx.
  NrIceStats stats = restartCtx->Destroy();
  restartCtx = nullptr;
  mIceCtxHdlr->ctx()->AccumulateStats(stats);
}
static void
AddNewIceStreamForRestart_s(RefPtr<PeerConnectionMedia> aPCMedia,
                            RefPtr<TransportFlow> aFlow,
                            size_t aLevel,
                            bool aIsRtcp)
{
  TransportLayerIce* ice =
      static_cast<TransportLayerIce*>(aFlow->GetLayer("ice"));
  ice->SetParameters(aPCMedia->ice_media_stream(aLevel),
                     aIsRtcp ? 2 : 1);
}
void
PeerConnectionMedia::FinalizeIceRestart_s()
{
  ASSERT_ON_THREAD(mSTSThread);

  // reset old streams since we don't need them anymore
  for (auto& transportFlow : mTransportFlows) {
    RefPtr<TransportFlow> aFlow = transportFlow.second;
    if (!aFlow) continue;
    TransportLayerIce* ice =
      static_cast<TransportLayerIce*>(aFlow->GetLayer(TransportLayerIce::ID()));
    ice->ResetOldStream();
  }

  mIceCtxHdlr->FinalizeIceRestart();
}
// Accessing the PCMedia should be safe here because we shouldn't
// have enqueued this function unless it was still active and
// the ICE data is destroyed on the STS.
static void
FinalizeTransportFlow_s(RefPtr<PeerConnectionMedia> aPCMedia,
                        RefPtr<TransportFlow> aFlow, size_t aLevel,
                        bool aIsRtcp,
                        nsAutoPtr<PtrVector<TransportLayer> > aLayerList)
{
  TransportLayerIce* ice =
      static_cast<TransportLayerIce*>(aLayerList->values.front());
  ice->SetParameters(aPCMedia->ice_media_stream(aLevel),
                     aIsRtcp ? 2 : 1);
  nsAutoPtr<std::queue<TransportLayer*> > layerQueue(
      new std::queue<TransportLayer*>);
  for (auto& value : aLayerList->values) {
    layerQueue->push(value);
  }
  aLayerList->values.clear();
  (void)aFlow->PushLayers(layerQueue); // TODO(bug 854518): Process errors.
}
void
PeerConnectionMedia::RollbackIceRestart_s()
{
  ASSERT_ON_THREAD(mSTSThread);

  // hold the restart context so we can disconnect signals
  RefPtr<NrIceCtx> restartCtx = mIceCtxHdlr->ctx();

  // restore old streams since we're rolling back
  for (auto i = mTransportFlows.begin();
       i != mTransportFlows.end();
       ++i) {
    RefPtr<TransportFlow> aFlow = i->second;
    if (!aFlow) continue;
    TransportLayerIce* ice =
      static_cast<TransportLayerIce*>(aFlow->GetLayer(TransportLayerIce::ID()));
    ice->RestoreOldStream();
  }

  mIceCtxHdlr->RollbackIceRestart();
  ConnectSignals(mIceCtxHdlr->ctx().get(), restartCtx.get());
}