Commit 061e2a06 authored by Henrik Boström's avatar Henrik Boström Committed by Commit Bot

RTCPeerConnection wired up to use CallSetupStateTracker.

This makes the RTCPeerConnection aware, through the help of the tracker,
what its call setup state is. This is confirmed by unittests.

UMA metrics and trigger point for collecting this will be added in a
follow-up CL.

Bug: 906029
Change-Id: Ib71ec03d7560c5ee9ac65fd5427b297808e8c4fa
Reviewed-on: https://chromium-review.googlesource.com/c/1349340Reviewed-by: default avatarHarald Alvestrand <hta@chromium.org>
Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Commit-Queue: Henrik Boström <hbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611088}
parent 52a2c835
......@@ -78,6 +78,7 @@ blink_modules_sources("peerconnection") {
"rtc_rtp_transceiver.h",
"rtc_session_description.cc",
"rtc_session_description.h",
"rtc_session_description_enums.h",
"rtc_session_description_request_impl.cc",
"rtc_session_description_request_impl.h",
"rtc_session_description_request_promise_impl.cc",
......
......@@ -545,6 +545,50 @@ base::Optional<SdpFormat> DeduceSdpFormat(const String& type,
return SdpFormat::kComplexUnifiedPlan;
}
RTCSetSessionDescriptionOperation GetRTCVoidRequestOperationType(
RTCPeerConnection::SetSdpOperationType operation,
const RTCSessionDescriptionInit& description) {
switch (operation) {
case RTCPeerConnection::SetSdpOperationType::kSetLocalDescription:
if (description.type() == "offer")
return RTCSetSessionDescriptionOperation::kSetLocalDescriptionOffer;
if (description.type() == "answer" || description.type() == "pranswer")
return RTCSetSessionDescriptionOperation::kSetLocalDescriptionAnswer;
return RTCSetSessionDescriptionOperation::kSetLocalDescriptionInvalidType;
case RTCPeerConnection::SetSdpOperationType::kSetRemoteDescription:
if (description.type() == "offer")
return RTCSetSessionDescriptionOperation::kSetRemoteDescriptionOffer;
if (description.type() == "answer" || description.type() == "pranswer")
return RTCSetSessionDescriptionOperation::kSetRemoteDescriptionAnswer;
return RTCSetSessionDescriptionOperation::
kSetRemoteDescriptionInvalidType;
}
}
void NoteCallSetupStateEventPending(
CallSetupStateTracker* tracker,
RTCPeerConnection::SetSdpOperationType operation,
const RTCSessionDescriptionInit& description) {
switch (operation) {
case RTCPeerConnection::SetSdpOperationType::kSetLocalDescription:
if (description.type() == "offer") {
tracker->NoteOffererStateEvent(OffererState::kSetLocalOfferPending);
} else if (description.type() == "answer" ||
description.type() == "pranswer") {
tracker->NoteAnswererStateEvent(AnswererState::kSetLocalAnswerPending);
}
break;
case RTCPeerConnection::SetSdpOperationType::kSetRemoteDescription:
if (description.type() == "offer") {
tracker->NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending);
} else if (description.type() == "answer" ||
description.type() == "pranswer") {
tracker->NoteOffererStateEvent(OffererState::kSetRemoteAnswerPending);
}
break;
}
}
} // namespace
SdpUsageCategory DeduceSdpUsageCategory(const String& sdp_type,
......@@ -750,12 +794,14 @@ ScriptPromise RTCPeerConnection::createOffer(ScriptState* script_state,
script_state, DOMException::Create(DOMExceptionCode::kInvalidStateError,
kSignalingStateClosedMessage));
}
call_setup_state_tracker_.NoteOffererStateEvent(
OffererState::kCreateOfferPending);
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
RTCSessionDescriptionRequest* request =
RTCSessionDescriptionRequestPromiseImpl::Create(
this, resolver, "RTCPeerConnection", "createOffer");
RTCCreateSessionDescriptionOperation::kCreateOffer, this, resolver,
"RTCPeerConnection", "createOffer");
if (options->hasOfferToReceiveAudio() || options->hasOfferToReceiveVideo()) {
ExecutionContext* context = ExecutionContext::From(script_state);
UseCounter::Count(
......@@ -784,9 +830,13 @@ ScriptPromise RTCPeerConnection::createOffer(
ParseOfferOptions(rtc_offer_options, exception_state);
if (exception_state.HadException())
return ScriptPromise();
call_setup_state_tracker_.NoteOffererStateEvent(
OffererState::kCreateOfferPending);
RTCSessionDescriptionRequest* request =
RTCSessionDescriptionRequestImpl::Create(
GetExecutionContext(), this, success_callback, error_callback);
GetExecutionContext(),
RTCCreateSessionDescriptionOperation::kCreateOffer, this,
success_callback, error_callback);
if (offer_options) {
if (offer_options->OfferToReceiveAudio() != -1 ||
......@@ -837,11 +887,14 @@ ScriptPromise RTCPeerConnection::createAnswer(ScriptState* script_state,
kSignalingStateClosedMessage));
}
call_setup_state_tracker_.NoteAnswererStateEvent(
AnswererState::kCreateAnswerPending);
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
RTCSessionDescriptionRequest* request =
RTCSessionDescriptionRequestPromiseImpl::Create(
this, resolver, "RTCPeerConnection", "createAnswer");
RTCCreateSessionDescriptionOperation::kCreateAnswer, this, resolver,
"RTCPeerConnection", "createAnswer");
peer_handler_->CreateAnswer(request, ConvertToWebRTCAnswerOptions(options));
return promise;
}
......@@ -881,9 +934,13 @@ ScriptPromise RTCPeerConnection::createAnswer(
return ScriptPromise::CastUndefined(script_state);
}
call_setup_state_tracker_.NoteAnswererStateEvent(
AnswererState::kCreateAnswerPending);
RTCSessionDescriptionRequest* request =
RTCSessionDescriptionRequestImpl::Create(
GetExecutionContext(), this, success_callback, error_callback);
GetExecutionContext(),
RTCCreateSessionDescriptionOperation::kCreateAnswer, this,
success_callback, error_callback);
peer_handler_->CreateAnswer(request, constraints);
return ScriptPromise::CastUndefined(script_state);
}
......@@ -944,6 +1001,58 @@ bool RTCPeerConnection::ShouldShowComplexPlanBSdpWarning(
return *sdp_format == SdpFormat::kComplexPlanB;
}
const CallSetupStateTracker& RTCPeerConnection::call_setup_state_tracker()
const {
return call_setup_state_tracker_;
}
void RTCPeerConnection::NoteSessionDescriptionRequestCompleted(
RTCCreateSessionDescriptionOperation operation,
bool success) {
switch (operation) {
case RTCCreateSessionDescriptionOperation::kCreateOffer:
call_setup_state_tracker_.NoteOffererStateEvent(
success ? OffererState::kCreateOfferResolved
: OffererState::kCreateOfferRejected);
return;
case RTCCreateSessionDescriptionOperation::kCreateAnswer:
call_setup_state_tracker_.NoteAnswererStateEvent(
success ? AnswererState::kCreateAnswerResolved
: AnswererState::kCreateAnswerRejected);
return;
}
}
void RTCPeerConnection::NoteVoidRequestCompleted(
RTCSetSessionDescriptionOperation operation,
bool success) {
switch (operation) {
case RTCSetSessionDescriptionOperation::kSetLocalDescriptionOffer:
call_setup_state_tracker_.NoteOffererStateEvent(
success ? OffererState::kSetLocalOfferResolved
: OffererState::kSetLocalOfferRejected);
break;
case RTCSetSessionDescriptionOperation::kSetLocalDescriptionAnswer:
call_setup_state_tracker_.NoteAnswererStateEvent(
success ? AnswererState::kSetLocalAnswerResolved
: AnswererState::kSetLocalAnswerRejected);
break;
case RTCSetSessionDescriptionOperation::kSetRemoteDescriptionOffer:
call_setup_state_tracker_.NoteAnswererStateEvent(
success ? AnswererState::kSetRemoteOfferResolved
: AnswererState::kSetRemoteOfferRejected);
break;
case RTCSetSessionDescriptionOperation::kSetRemoteDescriptionAnswer:
call_setup_state_tracker_.NoteOffererStateEvent(
success ? OffererState::kSetRemoteAnswerResolved
: OffererState::kSetRemoteAnswerRejected);
break;
case RTCSetSessionDescriptionOperation::kSetLocalDescriptionInvalidType:
case RTCSetSessionDescriptionOperation::kSetRemoteDescriptionInvalidType:
break;
}
}
void RTCPeerConnection::ReportSetSdpUsage(
SetSdpOperationType operation_type,
const RTCSessionDescriptionInit* session_description_init) const {
......@@ -992,9 +1101,14 @@ ScriptPromise RTCPeerConnection::setLocalDescription(
if (exception) {
return ScriptPromise::RejectWithDOMException(script_state, exception);
}
NoteCallSetupStateEventPending(&call_setup_state_tracker_,
SetSdpOperationType::kSetLocalDescription,
*session_description_init);
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
RTCVoidRequest* request = RTCVoidRequestPromiseImpl::Create(
GetRTCVoidRequestOperationType(SetSdpOperationType::kSetLocalDescription,
*session_description_init),
this, resolver, "RTCPeerConnection", "setLocalDescription");
peer_handler_->SetLocalDescription(
request, WebRTCSessionDescription(session_description_init->type(), sdp));
......@@ -1040,8 +1154,14 @@ ScriptPromise RTCPeerConnection::setLocalDescription(
return ScriptPromise::CastUndefined(script_state);
}
NoteCallSetupStateEventPending(&call_setup_state_tracker_,
SetSdpOperationType::kSetLocalDescription,
*session_description_init);
RTCVoidRequest* request = RTCVoidRequestImpl::Create(
GetExecutionContext(), this, success_callback, error_callback);
GetExecutionContext(),
GetRTCVoidRequestOperationType(SetSdpOperationType::kSetLocalDescription,
*session_description_init),
this, success_callback, error_callback);
peer_handler_->SetLocalDescription(
request, WebRTCSessionDescription(session_description_init->type(),
session_description_init->sdp()));
......@@ -1092,9 +1212,14 @@ ScriptPromise RTCPeerConnection::setRemoteDescription(
kSignalingStateClosedMessage));
}
NoteCallSetupStateEventPending(&call_setup_state_tracker_,
SetSdpOperationType::kSetRemoteDescription,
*session_description_init);
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
RTCVoidRequest* request = RTCVoidRequestPromiseImpl::Create(
GetRTCVoidRequestOperationType(SetSdpOperationType::kSetRemoteDescription,
*session_description_init),
this, resolver, "RTCPeerConnection", "setRemoteDescription");
peer_handler_->SetRemoteDescription(
request, WebRTCSessionDescription(session_description_init->type(),
......@@ -1135,8 +1260,14 @@ ScriptPromise RTCPeerConnection::setRemoteDescription(
if (CallErrorCallbackIfSignalingStateClosed(signaling_state_, error_callback))
return ScriptPromise::CastUndefined(script_state);
NoteCallSetupStateEventPending(&call_setup_state_tracker_,
SetSdpOperationType::kSetRemoteDescription,
*session_description_init);
RTCVoidRequest* request = RTCVoidRequestImpl::Create(
GetExecutionContext(), this, success_callback, error_callback);
GetExecutionContext(),
GetRTCVoidRequestOperationType(SetSdpOperationType::kSetRemoteDescription,
*session_description_init),
this, success_callback, error_callback);
peer_handler_->SetRemoteDescription(
request, WebRTCSessionDescription(session_description_init->type(),
session_description_init->sdp()));
......@@ -1452,7 +1583,7 @@ ScriptPromise RTCPeerConnection::addIceCandidate(
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
RTCVoidRequest* request = RTCVoidRequestPromiseImpl::Create(
this, resolver, "RTCPeerConnection", "addIceCandidate");
base::nullopt, this, resolver, "RTCPeerConnection", "addIceCandidate");
scoped_refptr<WebRTCICECandidate> web_candidate = ConvertToWebRTCIceCandidate(
ExecutionContext::From(script_state), candidate);
bool implemented =
......@@ -1484,8 +1615,9 @@ ScriptPromise RTCPeerConnection::addIceCandidate(
return ScriptPromise();
}
RTCVoidRequest* request = RTCVoidRequestImpl::Create(
GetExecutionContext(), this, success_callback, error_callback);
RTCVoidRequest* request =
RTCVoidRequestImpl::Create(GetExecutionContext(), base::nullopt, this,
success_callback, error_callback);
scoped_refptr<WebRTCICECandidate> web_candidate = ConvertToWebRTCIceCandidate(
ExecutionContext::From(script_state), candidate);
bool implemented =
......
......@@ -42,10 +42,14 @@
#include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/async_method_runner.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
namespace blink {
......@@ -310,6 +314,13 @@ class MODULES_EXPORT RTCPeerConnection final
// WebFeature::kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics.
bool ShouldShowComplexPlanBSdpWarning(const RTCSessionDescriptionInit*) const;
const CallSetupStateTracker& call_setup_state_tracker() const;
void NoteSessionDescriptionRequestCompleted(
RTCCreateSessionDescriptionOperation operation,
bool success);
void NoteVoidRequestCompleted(RTCSetSessionDescriptionOperation operation,
bool success);
void Trace(blink::Visitor*) override;
private:
......@@ -458,6 +469,7 @@ class MODULES_EXPORT RTCPeerConnection final
webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state_;
webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state_;
webrtc::PeerConnectionInterface::PeerConnectionState peer_connection_state_;
CallSetupStateTracker call_setup_state_tracker_;
// A map containing any track that is in use by the peer connection. This
// includes tracks of |rtp_senders_| and |rtp_receivers_|.
......
......@@ -8,21 +8,32 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
#include "third_party/blink/public/platform/web_rtc_session_description.h"
#include "third_party/blink/public/platform/web_rtc_session_description_request.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_callback.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_answer_options.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_configuration.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_server.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_offer_options.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_init.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h"
#include "third_party/webrtc/api/rtcerror.h"
#include "v8/include/v8.h"
namespace blink {
......@@ -359,7 +370,9 @@ static const char* kOfferSdpPlanBMultipleAudioTracks =
"a=ssrc:4092260337 mslabel:46f8615e-7599-49f3-9a45-3cf0faf58614\r\n"
"a=ssrc:4092260337 label:6b5f436e-f85d-40a1-83e4-acec63ca4b82\r\n";
class RTCPeerConnectionTest : public testing::Test {
template <typename PlatformSupportType>
class RTCPeerConnectionTestWithPlatformTestingPlatformType
: public testing::Test {
public:
RTCPeerConnection* CreatePC(V8TestingScope& scope,
const String& sdpSemantics = String()) {
......@@ -405,8 +418,14 @@ class RTCPeerConnectionTest : public testing::Test {
EXPECT_EQ("", GetExceptionMessage(scope));
}
private:
ScopedTestingPlatformSupport<TestingPlatformSupportWithWebRTC> platform;
protected:
ScopedTestingPlatformSupport<PlatformSupportType> platform_;
};
class RTCPeerConnectionTest
: public RTCPeerConnectionTestWithPlatformTestingPlatformType<
TestingPlatformSupportWithWebRTC> {
public:
};
TEST_F(RTCPeerConnectionTest, GetAudioTrack) {
......@@ -646,6 +665,382 @@ TEST_F(RTCPeerConnectionTest, PlanBSdpWarningNotShownForComplexUnifiedPlan) {
ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
}
enum class AsyncOperationAction {
kLeavePending,
kResolve,
kReject,
};
template <typename RequestType>
void CompleteRequest(RequestType request, bool resolve);
template <>
void CompleteRequest(WebRTCSessionDescriptionRequest request, bool resolve) {
if (resolve) {
WebRTCSessionDescription description =
WebRTCSessionDescription(WebString(), WebString());
request.RequestSucceeded(description);
} else {
request.RequestFailed(
webrtc::RTCError(webrtc::RTCErrorType::INVALID_MODIFICATION));
}
}
template <>
void CompleteRequest(WebRTCVoidRequest request, bool resolve) {
if (resolve) {
request.RequestSucceeded();
} else {
request.RequestFailed(
webrtc::RTCError(webrtc::RTCErrorType::INVALID_MODIFICATION));
}
}
template <typename RequestType>
void PostToCompleteRequest(AsyncOperationAction action,
const RequestType& request) {
switch (action) {
case AsyncOperationAction::kLeavePending:
return;
case AsyncOperationAction::kResolve:
scheduler::GetSequencedTaskRunnerForTesting()->PostTask(
FROM_HERE,
base::BindOnce(&CompleteRequest<RequestType>, request, true));
return;
case AsyncOperationAction::kReject:
scheduler::GetSequencedTaskRunnerForTesting()->PostTask(
FROM_HERE,
base::BindOnce(&CompleteRequest<RequestType>, request, false));
return;
}
}
class FakeWebRTCPeerConnectionHandler : public MockWebRTCPeerConnectionHandler {
public:
void CreateOffer(const WebRTCSessionDescriptionRequest& request,
const WebMediaConstraints&) override {
PostToCompleteRequest<WebRTCSessionDescriptionRequest>(
async_operation_action_, request);
}
void CreateOffer(const WebRTCSessionDescriptionRequest& request,
const WebRTCOfferOptions&) override {
PostToCompleteRequest<WebRTCSessionDescriptionRequest>(
async_operation_action_, request);
}
void CreateAnswer(const WebRTCSessionDescriptionRequest& request,
const WebMediaConstraints&) override {
PostToCompleteRequest<WebRTCSessionDescriptionRequest>(
async_operation_action_, request);
}
void CreateAnswer(const WebRTCSessionDescriptionRequest& request,
const WebRTCAnswerOptions&) override {
PostToCompleteRequest<WebRTCSessionDescriptionRequest>(
async_operation_action_, request);
}
void SetLocalDescription(const WebRTCVoidRequest& request,
const WebRTCSessionDescription&) override {
PostToCompleteRequest<WebRTCVoidRequest>(async_operation_action_, request);
}
void SetRemoteDescription(const WebRTCVoidRequest& request,
const WebRTCSessionDescription&) override {
PostToCompleteRequest<WebRTCVoidRequest>(async_operation_action_, request);
}
void set_async_operation_action(AsyncOperationAction action) {
async_operation_action_ = action;
}
private:
// Decides what to do with future async operations' promises/callbacks.
AsyncOperationAction async_operation_action_ =
AsyncOperationAction::kLeavePending;
};
class TestingPlatformSupportWithFakeWebRTC : public TestingPlatformSupport {
public:
std::unique_ptr<WebRTCPeerConnectionHandler> CreateRTCPeerConnectionHandler(
WebRTCPeerConnectionHandlerClient*,
scoped_refptr<base::SingleThreadTaskRunner>) override {
handler_ = new FakeWebRTCPeerConnectionHandler();
return std::unique_ptr<WebRTCPeerConnectionHandler>(handler_);
}
FakeWebRTCPeerConnectionHandler* handler() const { return handler_; }
private:
FakeWebRTCPeerConnectionHandler* handler_;
};
// These tests verifies the code paths for notifying the peer connection's
// CallSetupStateTracker of offerer and answerer events. Because fakes are used
// the test can pass empty SDP around, deciding whether to resolve or reject
// based on controlling the fake instead of validify of SDP, and
// platform_->RunUntilIdle() is enough to ensure a pending operation has
// completed. Without fakes we would have had to await promises and callbacks,
// passing SDP returned by one operation to the next.
class RTCPeerConnectionCallSetupStateTest
: public RTCPeerConnectionTestWithPlatformTestingPlatformType<
TestingPlatformSupportWithFakeWebRTC> {
public:
RTCPeerConnection* Initialize(V8TestingScope& scope) {
RTCPeerConnection* pc = CreatePC(scope);
tracker_ = &pc->call_setup_state_tracker();
SetNextOperationIsSuccessful(true);
return pc;
}
void SetNextOperationIsSuccessful(bool successful) {
platform_->handler()->set_async_operation_action(
successful ? AsyncOperationAction::kResolve
: AsyncOperationAction::kReject);
}
RTCSessionDescriptionInit* EmptyOffer() {
auto* sdp = RTCSessionDescriptionInit::Create();
sdp->setType("offer");
return sdp;
}
RTCSessionDescriptionInit* EmptyAnswer() {
auto* sdp = RTCSessionDescriptionInit::Create();
sdp->setType("answer");
return sdp;
}
template <typename CallbackType>
CallbackType* CreateEmptyCallback(V8TestingScope& scope) {
v8::Local<v8::Function> v8_function =
v8::Function::New(scope.GetContext(), EmptyHandler).ToLocalChecked();
return CallbackType::Create(v8_function);
}
Dictionary ToDictionary(V8TestingScope& scope,
const IDLDictionaryBase* value) {
return Dictionary(
scope.GetIsolate(),
ToV8(value, scope.GetContext()->Global(), scope.GetIsolate()),
scope.GetExceptionState());
}
private:
static void EmptyHandler(const v8::FunctionCallbackInfo<v8::Value>& args) {}
protected:
const CallSetupStateTracker* tracker_ = nullptr;
};
TEST_F(RTCPeerConnectionCallSetupStateTest, InitialState) {
V8TestingScope scope;
Initialize(scope);
EXPECT_EQ(OffererState::kNotStarted, tracker_->offerer_state());
EXPECT_EQ(AnswererState::kNotStarted, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kNotStarted, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest, OffererSucceeded) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// createOffer()
pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create());
EXPECT_EQ(OffererState::kCreateOfferPending, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->CallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kCreateOfferResolved, tracker_->offerer_state());
// setLocalDescription(offer)
pc->setLocalDescription(scope.GetScriptState(), EmptyOffer());
EXPECT_EQ(OffererState::kSetLocalOfferPending, tracker_->offerer_state());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetLocalOfferResolved, tracker_->offerer_state());
// setRemoteDescription(answer)
pc->setRemoteDescription(scope.GetScriptState(), EmptyAnswer());
EXPECT_EQ(OffererState::kSetRemoteAnswerPending, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->CallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetRemoteAnswerResolved, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kSucceeded, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest, OffererFailedAtCreateOffer) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// createOffer()
SetNextOperationIsSuccessful(false);
pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kCreateOfferRejected, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest,
OffererFailedAtSetLocalDescription) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// createOffer()
pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create());
platform_->RunUntilIdle();
// setLocalDescription(offer)
SetNextOperationIsSuccessful(false);
pc->setLocalDescription(scope.GetScriptState(), EmptyOffer());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetLocalOfferRejected, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest,
OffererFailedAtSetRemoteDescription) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// createOffer()
pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create());
platform_->RunUntilIdle();
// setLocalDescription(offer)
pc->setLocalDescription(scope.GetScriptState(), EmptyOffer());
platform_->RunUntilIdle();
// setRemoteDescription(answer)
SetNextOperationIsSuccessful(false);
pc->setRemoteDescription(scope.GetScriptState(), EmptyAnswer());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetRemoteAnswerRejected, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest, OffererLegacyApiPath) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// Legacy createOffer() with callbacks
pc->createOffer(scope.GetScriptState(),
CreateEmptyCallback<V8RTCSessionDescriptionCallback>(scope),
CreateEmptyCallback<V8RTCPeerConnectionErrorCallback>(scope),
ToDictionary(scope, RTCOfferOptions::Create()),
scope.GetExceptionState());
EXPECT_EQ(OffererState::kCreateOfferPending, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->CallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kCreateOfferResolved, tracker_->offerer_state());
// Legacy setLocalDescription(offer) with callbacks
pc->setLocalDescription(
scope.GetScriptState(), EmptyOffer(),
CreateEmptyCallback<V8VoidFunction>(scope),
CreateEmptyCallback<V8RTCPeerConnectionErrorCallback>(scope));
EXPECT_EQ(OffererState::kSetLocalOfferPending, tracker_->offerer_state());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetLocalOfferResolved, tracker_->offerer_state());
// Legacy setRemoteDescription(answer) with callbacks
pc->setRemoteDescription(
scope.GetScriptState(), EmptyAnswer(),
CreateEmptyCallback<V8VoidFunction>(scope),
CreateEmptyCallback<V8RTCPeerConnectionErrorCallback>(scope));
EXPECT_EQ(OffererState::kSetRemoteAnswerPending, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->CallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetRemoteAnswerResolved, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kSucceeded, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest, AnswererSucceeded) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// setRemoteDescription(offer)
pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer());
EXPECT_EQ(AnswererState::kSetRemoteOfferPending, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->CallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetRemoteOfferResolved, tracker_->answerer_state());
// createAnswer()
pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create());
EXPECT_EQ(AnswererState::kCreateAnswerPending, tracker_->answerer_state());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kCreateAnswerResolved, tracker_->answerer_state());
// setLocalDescription(answer)
pc->setLocalDescription(scope.GetScriptState(), EmptyAnswer());
EXPECT_EQ(AnswererState::kSetLocalAnswerPending, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->CallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetLocalAnswerResolved, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kSucceeded, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest,
AnswererFailedAtSetRemoteDescription) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// setRemoteDescription(offer)
SetNextOperationIsSuccessful(false);
pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetRemoteOfferRejected, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest, AnswererFailedAtCreateAnswer) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// setRemoteDescription(offer)
pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer());
platform_->RunUntilIdle();
// createAnswer()
SetNextOperationIsSuccessful(false);
pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kCreateAnswerRejected, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest,
AnswererFailedAtSetLocalDescription) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// setRemoteDescription(offer)
pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer());
platform_->RunUntilIdle();
// createAnswer()
pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create());
platform_->RunUntilIdle();
// setLocalDescription(answer)
SetNextOperationIsSuccessful(false);
pc->setLocalDescription(scope.GetScriptState(), EmptyAnswer());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetLocalAnswerRejected, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->CallSetupState());
}
TEST_F(RTCPeerConnectionCallSetupStateTest, AnswererLegacyApiPath) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// Legacy setRemoteDescription(offer) with callbacks
pc->setRemoteDescription(
scope.GetScriptState(), EmptyOffer(),
CreateEmptyCallback<V8VoidFunction>(scope),
CreateEmptyCallback<V8RTCPeerConnectionErrorCallback>(scope));
EXPECT_EQ(AnswererState::kSetRemoteOfferPending, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->CallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetRemoteOfferResolved, tracker_->answerer_state());
// Legacy createAnswer() with callbacks
pc->createAnswer(scope.GetScriptState(),
CreateEmptyCallback<V8RTCSessionDescriptionCallback>(scope),
CreateEmptyCallback<V8RTCPeerConnectionErrorCallback>(scope),
Dictionary() /* media_constraints */);
EXPECT_EQ(AnswererState::kCreateAnswerPending, tracker_->answerer_state());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kCreateAnswerResolved, tracker_->answerer_state());
// Legacy setLocalDescription(answer) with callbacks
pc->setLocalDescription(
scope.GetScriptState(), EmptyAnswer(),
CreateEmptyCallback<V8VoidFunction>(scope),
CreateEmptyCallback<V8RTCPeerConnectionErrorCallback>(scope));
EXPECT_EQ(AnswererState::kSetLocalAnswerPending, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->CallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetLocalAnswerResolved, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kSucceeded, tracker_->CallSetupState());
}
// Test that simple Plan B is considered safe regardless of configurations.
TEST(DeduceSdpUsageCategory, SimplePlanBIsAlwaysSafe) {
// If the default is Plan B.
......
// Copyright 2018 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_SESSION_DESCRIPTION_ENUMS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_SESSION_DESCRIPTION_ENUMS_H_
namespace blink {
// RTCPeerConnection methods that are used to create session descriptions (SDP).
// See RTCPeerConnection::createOffer() and RTCPeerConnection::createAnswer().
enum class RTCCreateSessionDescriptionOperation {
kCreateOffer,
kCreateAnswer,
};
// RTCPeerConnection operations that are used to set session descriptions (SDP).
// See methods RTCPeerConnection::setLocalDescription() and
// RTCPeerConnection::setRemoteDescription() - the SDP parameter can have the
// type "offer" or "answer".
enum class RTCSetSessionDescriptionOperation {
kSetLocalDescriptionOffer,
kSetLocalDescriptionAnswer,
kSetLocalDescriptionInvalidType,
kSetRemoteDescriptionOffer,
kSetRemoteDescriptionAnswer,
kSetRemoteDescriptionInvalidType,
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_SESSION_DESCRIPTION_ENUMS_H_
......@@ -41,19 +41,22 @@ namespace blink {
RTCSessionDescriptionRequestImpl* RTCSessionDescriptionRequestImpl::Create(
ExecutionContext* context,
RTCCreateSessionDescriptionOperation operation,
RTCPeerConnection* requester,
V8RTCSessionDescriptionCallback* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback) {
return new RTCSessionDescriptionRequestImpl(context, requester,
return new RTCSessionDescriptionRequestImpl(context, operation, requester,
success_callback, error_callback);
}
RTCSessionDescriptionRequestImpl::RTCSessionDescriptionRequestImpl(
ExecutionContext* context,
RTCCreateSessionDescriptionOperation operation,
RTCPeerConnection* requester,
V8RTCSessionDescriptionCallback* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback)
: ContextLifecycleObserver(context),
operation_(operation),
success_callback_(ToV8PersistentCallbackFunction(success_callback)),
error_callback_(ToV8PersistentCallbackFunction(error_callback)),
requester_(requester) {
......@@ -67,6 +70,7 @@ void RTCSessionDescriptionRequestImpl::RequestSucceeded(
bool should_fire_callback =
requester_ ? requester_->ShouldFireDefaultCallbacks() : false;
if (should_fire_callback && success_callback_) {
requester_->NoteSessionDescriptionRequestCompleted(operation_, true);
auto* description = RTCSessionDescription::Create(web_session_description);
requester_->NoteSdpCreated(*description);
success_callback_->InvokeAndReportException(nullptr, description);
......@@ -79,6 +83,7 @@ void RTCSessionDescriptionRequestImpl::RequestFailed(
bool should_fire_callback =
requester_ ? requester_->ShouldFireDefaultCallbacks() : false;
if (should_fire_callback && error_callback_) {
requester_->NoteSessionDescriptionRequestCompleted(operation_, false);
error_callback_->InvokeAndReportException(
nullptr, CreateDOMExceptionFromRTCError(error));
}
......
......@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_callback.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h"
......@@ -43,6 +44,9 @@ namespace blink {
class RTCPeerConnection;
class WebRTCSessionDescription;
// TODO(https://crbug.com/908468): Split up the operation-specific codepaths
// into separate request implementations and find a way to consolidate the
// shared code as to not repeat the majority of the implementations.
class RTCSessionDescriptionRequestImpl final
: public RTCSessionDescriptionRequest,
public ContextLifecycleObserver {
......@@ -51,6 +55,7 @@ class RTCSessionDescriptionRequestImpl final
public:
static RTCSessionDescriptionRequestImpl* Create(
ExecutionContext*,
RTCCreateSessionDescriptionOperation,
RTCPeerConnection*,
V8RTCSessionDescriptionCallback*,
V8RTCPeerConnectionErrorCallback*);
......@@ -66,12 +71,14 @@ class RTCSessionDescriptionRequestImpl final
private:
RTCSessionDescriptionRequestImpl(ExecutionContext*,
RTCCreateSessionDescriptionOperation,
RTCPeerConnection*,
V8RTCSessionDescriptionCallback*,
V8RTCPeerConnectionErrorCallback*);
void Clear();
RTCCreateSessionDescriptionOperation operation_;
// This request object is held by WebRTCPeerConnectionHandler, which doesn't
// support wrapper-tracing. Thus, this object holds the underlying callback
// functions as persistent handles. This is acceptable because the request
......
......@@ -14,20 +14,25 @@
namespace blink {
RTCSessionDescriptionRequestPromiseImpl*
RTCSessionDescriptionRequestPromiseImpl::Create(RTCPeerConnection* requester,
ScriptPromiseResolver* resolver,
const char* interface_name,
const char* property_name) {
RTCSessionDescriptionRequestPromiseImpl::Create(
RTCCreateSessionDescriptionOperation operation,
RTCPeerConnection* requester,
ScriptPromiseResolver* resolver,
const char* interface_name,
const char* property_name) {
return new RTCSessionDescriptionRequestPromiseImpl(
requester, resolver, interface_name, property_name);
operation, requester, resolver, interface_name, property_name);
}
RTCSessionDescriptionRequestPromiseImpl::
RTCSessionDescriptionRequestPromiseImpl(RTCPeerConnection* requester,
ScriptPromiseResolver* resolver,
const char* interface_name,
const char* property_name)
: requester_(requester),
RTCSessionDescriptionRequestPromiseImpl(
RTCCreateSessionDescriptionOperation operation,
RTCPeerConnection* requester,
ScriptPromiseResolver* resolver,
const char* interface_name,
const char* property_name)
: operation_(operation),
requester_(requester),
resolver_(resolver),
interface_name_(interface_name),
property_name_(property_name) {
......@@ -41,6 +46,7 @@ RTCSessionDescriptionRequestPromiseImpl::
void RTCSessionDescriptionRequestPromiseImpl::RequestSucceeded(
const WebRTCSessionDescription& web_session_description) {
if (requester_ && requester_->ShouldFireDefaultCallbacks()) {
requester_->NoteSessionDescriptionRequestCompleted(operation_, true);
auto* description = RTCSessionDescription::Create(web_session_description);
requester_->NoteSdpCreated(*description);
resolver_->Resolve(description);
......@@ -56,6 +62,7 @@ void RTCSessionDescriptionRequestPromiseImpl::RequestSucceeded(
void RTCSessionDescriptionRequestPromiseImpl::RequestFailed(
const webrtc::RTCError& error) {
if (requester_ && requester_->ShouldFireDefaultCallbacks()) {
requester_->NoteSessionDescriptionRequestCompleted(operation_, false);
ScriptState::Scope scope(resolver_->GetScriptState());
ExceptionState exception_state(resolver_->GetScriptState()->GetIsolate(),
ExceptionState::kExecutionContext,
......
......@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_SESSION_DESCRIPTION_REQUEST_PROMISE_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_SESSION_DESCRIPTION_REQUEST_PROMISE_IMPL_H_
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
......@@ -14,10 +15,14 @@ class RTCPeerConnection;
class ScriptPromiseResolver;
class WebRTCSessionDescription;
// TODO(https://crbug.com/908468): Split up the operation-specific codepaths
// into separate request implementations and find a way to consolidate the
// shared code as to not repeat the majority of the implementations.
class RTCSessionDescriptionRequestPromiseImpl final
: public RTCSessionDescriptionRequest {
public:
static RTCSessionDescriptionRequestPromiseImpl* Create(
RTCCreateSessionDescriptionOperation,
RTCPeerConnection*,
ScriptPromiseResolver*,
const char* interface_name,
......@@ -31,13 +36,15 @@ class RTCSessionDescriptionRequestPromiseImpl final
void Trace(blink::Visitor*) override;
private:
RTCSessionDescriptionRequestPromiseImpl(RTCPeerConnection*,
RTCSessionDescriptionRequestPromiseImpl(RTCCreateSessionDescriptionOperation,
RTCPeerConnection*,
ScriptPromiseResolver*,
const char* interface_name,
const char* property_name);
void Clear();
RTCCreateSessionDescriptionOperation operation_;
Member<RTCPeerConnection> requester_;
Member<ScriptPromiseResolver> resolver_;
const char* interface_name_;
......
......@@ -38,19 +38,22 @@ namespace blink {
RTCVoidRequestImpl* RTCVoidRequestImpl::Create(
ExecutionContext* context,
base::Optional<RTCSetSessionDescriptionOperation> operation,
RTCPeerConnection* requester,
V8VoidFunction* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback) {
return new RTCVoidRequestImpl(context, requester, success_callback,
error_callback);
return new RTCVoidRequestImpl(context, std::move(operation), requester,
success_callback, error_callback);
}
RTCVoidRequestImpl::RTCVoidRequestImpl(
ExecutionContext* context,
base::Optional<RTCSetSessionDescriptionOperation> operation,
RTCPeerConnection* requester,
V8VoidFunction* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback)
: ContextLifecycleObserver(context),
operation_(std::move(operation)),
success_callback_(ToV8PersistentCallbackFunction(success_callback)),
error_callback_(ToV8PersistentCallbackFunction(error_callback)),
requester_(requester) {
......@@ -62,8 +65,11 @@ RTCVoidRequestImpl::~RTCVoidRequestImpl() = default;
void RTCVoidRequestImpl::RequestSucceeded() {
bool should_fire_callback =
requester_ && requester_->ShouldFireDefaultCallbacks();
if (should_fire_callback && success_callback_)
if (should_fire_callback && success_callback_) {
if (operation_)
requester_->NoteVoidRequestCompleted(*operation_, true);
success_callback_->InvokeAndReportException(nullptr);
}
Clear();
}
......@@ -72,6 +78,8 @@ void RTCVoidRequestImpl::RequestFailed(const webrtc::RTCError& error) {
bool should_fire_callback =
requester_ && requester_->ShouldFireDefaultCallbacks();
if (should_fire_callback && error_callback_.Get()) {
if (operation_)
requester_->NoteVoidRequestCompleted(*operation_, false);
error_callback_->InvokeAndReportException(
nullptr, CreateDOMExceptionFromRTCError(error));
}
......
......@@ -31,9 +31,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_VOID_REQUEST_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_VOID_REQUEST_IMPL_H_
#include "base/optional.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
......@@ -41,15 +43,20 @@ namespace blink {
class RTCPeerConnection;
// TODO(https://crbug.com/908468): Split up the operation-specific codepaths
// into separate request implementations and find a way to consolidate the
// shared code as to not repeat the majority of the implementations.
class RTCVoidRequestImpl final : public RTCVoidRequest,
public ContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(RTCVoidRequestImpl);
public:
static RTCVoidRequestImpl* Create(ExecutionContext*,
RTCPeerConnection*,
V8VoidFunction*,
V8RTCPeerConnectionErrorCallback*);
static RTCVoidRequestImpl* Create(
ExecutionContext*,
base::Optional<RTCSetSessionDescriptionOperation>,
RTCPeerConnection*,
V8VoidFunction*,
V8RTCPeerConnectionErrorCallback*);
~RTCVoidRequestImpl() override;
// RTCVoidRequest
......@@ -63,12 +70,14 @@ class RTCVoidRequestImpl final : public RTCVoidRequest,
private:
RTCVoidRequestImpl(ExecutionContext*,
base::Optional<RTCSetSessionDescriptionOperation>,
RTCPeerConnection*,
V8VoidFunction*,
V8RTCPeerConnectionErrorCallback*);
void Clear();
base::Optional<RTCSetSessionDescriptionOperation> operation_;
// This request object is held by WebRTCPeerConnectionHandler, which doesn't
// support wrapper-tracing. Thus, this object holds the underlying callback
// functions as persistent handles. This is acceptable because the request
......
......@@ -12,20 +12,23 @@
namespace blink {
RTCVoidRequestPromiseImpl* RTCVoidRequestPromiseImpl::Create(
base::Optional<RTCSetSessionDescriptionOperation> operation,
RTCPeerConnection* requester,
ScriptPromiseResolver* resolver,
const char* interface_name,
const char* property_name) {
return new RTCVoidRequestPromiseImpl(requester, resolver, interface_name,
property_name);
return new RTCVoidRequestPromiseImpl(std::move(operation), requester,
resolver, interface_name, property_name);
}
RTCVoidRequestPromiseImpl::RTCVoidRequestPromiseImpl(
base::Optional<RTCSetSessionDescriptionOperation> operation,
RTCPeerConnection* requester,
ScriptPromiseResolver* resolver,
const char* interface_name,
const char* property_name)
: requester_(requester),
: operation_(std::move(operation)),
requester_(requester),
resolver_(resolver),
interface_name_(interface_name),
property_name_(property_name) {
......@@ -37,6 +40,8 @@ RTCVoidRequestPromiseImpl::~RTCVoidRequestPromiseImpl() = default;
void RTCVoidRequestPromiseImpl::RequestSucceeded() {
if (requester_ && requester_->ShouldFireDefaultCallbacks()) {
if (operation_)
requester_->NoteVoidRequestCompleted(*operation_, true);
resolver_->Resolve();
} else {
// This is needed to have the resolver release its internal resources
......@@ -49,6 +54,8 @@ void RTCVoidRequestPromiseImpl::RequestSucceeded() {
void RTCVoidRequestPromiseImpl::RequestFailed(const webrtc::RTCError& error) {
if (requester_ && requester_->ShouldFireDefaultCallbacks()) {
if (operation_)
requester_->NoteVoidRequestCompleted(*operation_, false);
ScriptState::Scope scope(resolver_->GetScriptState());
ExceptionState exception_state(resolver_->GetScriptState()->GetIsolate(),
ExceptionState::kExecutionContext,
......
......@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_VOID_REQUEST_PROMISE_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_VOID_REQUEST_PROMISE_IMPL_H_
#include "base/optional.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
......@@ -13,12 +15,17 @@ namespace blink {
class ScriptPromiseResolver;
class RTCPeerConnection;
// TODO(https://crbug.com/908468): Split up the operation-specific codepaths
// into separate request implementations and find a way to consolidate the
// shared code as to not repeat the majority of the implementations.
class RTCVoidRequestPromiseImpl final : public RTCVoidRequest {
public:
static RTCVoidRequestPromiseImpl* Create(RTCPeerConnection*,
ScriptPromiseResolver*,
const char* interface_name,
const char* property_name);
static RTCVoidRequestPromiseImpl* Create(
base::Optional<RTCSetSessionDescriptionOperation>,
RTCPeerConnection*,
ScriptPromiseResolver*,
const char* interface_name,
const char* property_name);
~RTCVoidRequestPromiseImpl() override;
// RTCVoidRequest
......@@ -28,13 +35,15 @@ class RTCVoidRequestPromiseImpl final : public RTCVoidRequest {
void Trace(blink::Visitor*) override;
private:
RTCVoidRequestPromiseImpl(RTCPeerConnection*,
RTCVoidRequestPromiseImpl(base::Optional<RTCSetSessionDescriptionOperation>,
RTCPeerConnection*,
ScriptPromiseResolver*,
const char* interface_name,
const char* property_name);
void Clear();
base::Optional<RTCSetSessionDescriptionOperation> operation_;
Member<RTCPeerConnection> requester_;
Member<ScriptPromiseResolver> resolver_;
const char* interface_name_;
......
......@@ -12,6 +12,9 @@
namespace blink {
// TODO(https://crbug.com/908461): This is currently implemented as NO-OPs or to
// create dummy objects whose methods return default values. Consider renaming
// the class, changing it to be GMOCK friendly or deleting it.
class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
public:
MockWebRTCPeerConnectionHandler();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment