blob: 08ad30a40a79158e9e3502e1cb2a651f59707586 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "modules/peerconnection/RTCRtpSender.h"
#include "bindings/core/v8/ScriptPromiseResolver.h"
#include "core/dom/DOMException.h"
#include "modules/mediastream/MediaStreamTrack.h"
#include "modules/peerconnection/RTCDTMFSender.h"
#include "modules/peerconnection/RTCPeerConnection.h"
#include "platform/peerconnection/RTCVoidRequest.h"
namespace blink {
namespace {
class ReplaceTrackRequest : public RTCVoidRequest {
public:
ReplaceTrackRequest(RTCRtpSender* sender,
MediaStreamTrack* with_track,
ScriptPromiseResolver* resolver)
: sender_(sender), with_track_(with_track), resolver_(resolver) {}
~ReplaceTrackRequest() override {}
void RequestSucceeded() override {
sender_->SetTrack(with_track_);
resolver_->Resolve();
}
// TODO(hbos): Surface RTCError instead of hard-coding which exception type to
// use. This requires the webrtc layer sender interface to be updated.
// https://crbug.com/webrtc/8690
void RequestFailed(const String& error) override {
resolver_->Reject(DOMException::Create(kInvalidModificationError, error));
}
void Trace(blink::Visitor* visitor) override {
visitor->Trace(sender_);
visitor->Trace(with_track_);
visitor->Trace(resolver_);
RTCVoidRequest::Trace(visitor);
}
private:
Member<RTCRtpSender> sender_;
Member<MediaStreamTrack> with_track_;
Member<ScriptPromiseResolver> resolver_;
};
} // namespace
RTCRtpSender::RTCRtpSender(RTCPeerConnection* pc,
std::unique_ptr<WebRTCRtpSender> sender,
MediaStreamTrack* track,
MediaStreamVector streams)
: pc_(pc),
sender_(std::move(sender)),
track_(track),
streams_(std::move(streams)) {
DCHECK(pc_);
DCHECK(sender_);
DCHECK(track_);
}
MediaStreamTrack* RTCRtpSender::track() {
return track_;
}
ScriptPromise RTCRtpSender::replaceTrack(ScriptState* script_state,
MediaStreamTrack* with_track) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
if (pc_->IsClosed()) {
resolver->Reject(DOMException::Create(kInvalidStateError,
"The peer connection is closed."));
return promise;
}
WebMediaStreamTrack web_track;
if (with_track)
web_track = with_track->Component();
ReplaceTrackRequest* request =
new ReplaceTrackRequest(this, with_track, resolver);
sender_->ReplaceTrack(web_track, request);
return promise;
}
WebRTCRtpSender* RTCRtpSender::web_sender() {
return sender_.get();
}
void RTCRtpSender::SetTrack(MediaStreamTrack* track) {
track_ = track;
}
MediaStreamVector RTCRtpSender::streams() const {
return streams_;
}
RTCDTMFSender* RTCRtpSender::dtmf() {
// Lazy initialization of dtmf_ to avoid overhead when not used.
// TODO(hta): Redefine layers below to use sender as argument, and
// stop depending on track being present.
// https://crbug.com/814214
if (!dtmf_ && track_ && track_->kind() == "audio") {
ExceptionState exception_state(nullptr, ExceptionState::kUnknownContext,
nullptr, nullptr);
dtmf_ = pc_->createDTMFSender(track_, exception_state);
if (exception_state.HadException()) {
LOG(ERROR) << "Unable to create DTMF sender attribute on an audio sender:"
<< exception_state.Message();
}
}
return dtmf_;
}
void RTCRtpSender::Trace(blink::Visitor* visitor) {
visitor->Trace(pc_);
visitor->Trace(track_);
visitor->Trace(dtmf_);
visitor->Trace(streams_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink