Chromium Code Reviews| Index: chrome/renderer/extensions/webrtc_native_handler.cc |
| diff --git a/chrome/renderer/extensions/webrtc_native_handler.cc b/chrome/renderer/extensions/webrtc_native_handler.cc |
| index 8ea32ee30715358cb67f440c1a4770279393190a..dba18affd54ecf4160b64ec8e0eef3680e1ac89a 100644 |
| --- a/chrome/renderer/extensions/webrtc_native_handler.cc |
| +++ b/chrome/renderer/extensions/webrtc_native_handler.cc |
| @@ -5,11 +5,67 @@ |
| #include "chrome/renderer/extensions/webrtc_native_handler.h" |
| #include "base/logging.h" |
| +#include "chrome/common/extensions/api/webrtc_cast_send_transport.h" |
| +#include "chrome/common/extensions/api/webrtc_cast_udp_transport.h" |
| +#include "chrome/renderer/extensions/chrome_v8_context.h" |
| +#include "chrome/renderer/media/cast_session.h" |
| +#include "chrome/renderer/media/cast_send_transport.h" |
| +#include "chrome/renderer/media/cast_udp_transport.h" |
| +#include "content/public/renderer/v8_value_converter.h" |
| +#include "net/base/host_port_pair.h" |
| + |
| +using content::V8ValueConverter; |
| + |
| +// Extension types. |
| +using extensions::api::webrtc_cast_send_transport::RtpCaps; |
| +using extensions::api::webrtc_cast_send_transport::RtpParams; |
| +using extensions::api::webrtc_cast_send_transport::RtpPayloadParams; |
| +using extensions::api::webrtc_cast_udp_transport::CreateInfo; |
| +using extensions::api::webrtc_cast_udp_transport::UdpParams; |
| namespace extensions { |
| +namespace { |
| +const char kSendTransportNotFound[] = |
|
scherkus (not reviewing)
2013/10/29 17:38:17
can this fit on one line?
Alpha Left Google
2013/10/29 19:52:18
Done.
|
| + "The send transport cannot be found"; |
| +const char kUdpTransportNotFound[] = "The udp transport cannot be found"; |
|
scherkus (not reviewing)
2013/10/29 17:38:17
s/udp/UDP/
Alpha Left Google
2013/10/29 19:52:18
Done.
|
| +const char kInvalidUdpParams[] = "Invalid UDP params"; |
| +const char kInvalidRtpCaps[] = "Invalid value for RTP caps"; |
| +const char kInvalidRtpParams[] = "Invalid value for RTP params"; |
| +const char kUnableToConvertArgs[] = "Unable to convert arguments"; |
| +const char kUnableToConvertCaps[] = "Unable to convert caps"; |
| +const char kUnableToConvertParams[] = "Unable to convert params"; |
| + |
| +// Convert from extension API's RtpCaps to CastRtpCaps. |
| +bool ToCastRtpCaps(const RtpCaps& ext_caps, CastRtpCaps* cast_caps) { |
| + NOTIMPLEMENTED(); |
| + return true; |
| +} |
| + |
| +// Convert from CastRtpCaps to extension API's RtpCaps. |
| +bool FromCastRtpCaps(const CastRtpCaps& cast_caps, RtpCaps* ext_caps) { |
| + NOTIMPLEMENTED(); |
| + return true; |
| +} |
| + |
| +// Convert from extension API's RtpParams to CastRtpCaps. |
|
scherkus (not reviewing)
2013/10/29 17:38:17
s/CastRtpCaps/CastRtpParams/
Alpha Left Google
2013/10/29 19:52:18
Done.
|
| +bool ToCastRtpParams(const RtpParams& ext_params, CastRtpParams* cast_params) { |
| + NOTIMPLEMENTED(); |
| + return true; |
| +} |
| + |
| +// Convert from extension API's RtpParams to CastRtpCaps. |
|
scherkus (not reviewing)
2013/10/29 17:38:17
this comment is backwards
in fact, I'm not sure h
Alpha Left Google
2013/10/29 19:52:18
Okay. I removed them all.
|
| +bool FromCastRtpParams(const CastRtpParams& cast_params, |
| + RtpParams* ext_params) { |
| + NOTIMPLEMENTED(); |
| + return true; |
| +} |
| + |
| +} // namespace |
| + |
| WebRtcNativeHandler::WebRtcNativeHandler(ChromeV8Context* context) |
| - : ObjectBackedNativeHandler(context) { |
| + : ObjectBackedNativeHandler(context), |
| + last_transport_id_(0) { |
| RouteFunction("CreateCastSendTransport", |
| base::Bind(&WebRtcNativeHandler::CreateCastSendTransport, |
| base::Unretained(this))); |
| @@ -31,6 +87,9 @@ WebRtcNativeHandler::WebRtcNativeHandler(ChromeV8Context* context) |
| RouteFunction("CreateCastUdpTransport", |
| base::Bind(&WebRtcNativeHandler::CreateCastUdpTransport, |
| base::Unretained(this))); |
| + RouteFunction("DestroyCastUdpTransport", |
| + base::Bind(&WebRtcNativeHandler::DestroyCastUdpTransport, |
| + base::Unretained(this))); |
| RouteFunction("StartCastUdpTransport", |
| base::Bind(&WebRtcNativeHandler::StartCastUdpTransport, |
| base::Unretained(this))); |
| @@ -44,47 +103,254 @@ WebRtcNativeHandler::~WebRtcNativeHandler() { |
| void WebRtcNativeHandler::CreateCastSendTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(3, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
|
scherkus (not reviewing)
2013/10/29 17:38:17
what about args[1]?
also, is crashing really the
Alpha Left Google
2013/10/29 19:52:18
args[1] is a MediaStreamTrack and the extension sy
scherkus (not reviewing)
2013/10/29 23:47:22
I've found at least one counter-example :)
chrome/
|
| + CHECK(args[2]->IsFunction()); |
| + |
| + int inner_transport_id = static_cast<int>( |
|
scherkus (not reviewing)
2013/10/29 17:38:17
can this fit on one line?
Alpha Left Google
2013/10/29 19:52:18
Done.
|
| + args[0]->ToInt32()->Value()); |
| + CastUdpTransport* inner_transport = GetUdpTransport(inner_transport_id); |
| + if (!inner_transport) |
| + return; |
| + |
| + // TODO(hclam): Convert second argument from v8::Value to |
| + // WebMediaStreamTrack. |
| + int transport_id = last_transport_id_++; |
| + send_transport_map_[transport_id] = |
| + linked_ptr<CastSendTransport>( |
| + new CastSendTransport(inner_transport, NULL)); |
| + |
| + v8::Handle<v8::Value> transport_id_v8 = v8::Integer::New(transport_id); |
| + context()->CallFunction(v8::Handle<v8::Function>::Cast(args[2]), 1, |
| + &transport_id_v8); |
| } |
| void WebRtcNativeHandler::DestroyCastSendTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(1, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
| + |
| + int transport_id = static_cast<int>(args[0]->ToInt32()->Value()); |
| + CastSendTransport* transport = GetSendTransport(transport_id); |
| + if (!transport) |
| + return; |
| + send_transport_map_.erase(transport_id); |
| } |
| void WebRtcNativeHandler::CreateParamsCastSendTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(3, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
| + CHECK(args[1]->IsObject()); |
| + CHECK(args[2]->IsFunction()); |
| + |
| + int transport_id = static_cast<int>(args[0]->ToInt32()->Value()); |
| + CastSendTransport* transport = GetSendTransport(transport_id); |
| + if (!transport) |
| + return; |
| + |
| + scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| + scoped_ptr<Value> remote_caps_value( |
| + converter->FromV8Value(args[1], context()->v8_context())); |
| + if (!remote_caps_value) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kUnableToConvertArgs))); |
| + return; |
| + } |
| + scoped_ptr<RtpCaps> remote_caps = |
| + RtpCaps::FromValue(*remote_caps_value); |
| + if (!remote_caps) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kInvalidRtpCaps))); |
| + return; |
| + } |
| + |
| + CastRtpCaps cast_remote_caps; |
| + if (!ToCastRtpCaps(*remote_caps, &cast_remote_caps)) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kUnableToConvertCaps))); |
| + return; |
| + } |
| + CastRtpParams cast_params = transport->CreateParams(cast_remote_caps); |
| + RtpParams params; |
| + if (!FromCastRtpParams(cast_params, ¶ms)) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kUnableToConvertParams))); |
| + return; |
| + } |
| + |
| + scoped_ptr<base::DictionaryValue> params_value = params.ToValue(); |
| + v8::Handle<v8::Value> params_v8 = converter->ToV8Value( |
| + params_value.get(), context()->v8_context()); |
| + context()->CallFunction(v8::Handle<v8::Function>::Cast(args[2]), 1, |
| + ¶ms_v8); |
| } |
| void WebRtcNativeHandler::GetCapsCastSendTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(2, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
| + CHECK(args[1]->IsFunction()); |
| + |
| + int transport_id = static_cast<int>(args[0]->ToInt32()->Value()); |
| + CastSendTransport* transport = GetSendTransport(transport_id); |
| + if (!transport) |
| + return; |
| + |
| + CastRtpCaps cast_caps = transport->GetCaps(); |
| + RtpCaps caps; |
| + if (!FromCastRtpCaps(cast_caps, &caps)) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kUnableToConvertCaps))); |
| + return; |
| + } |
| + |
| + scoped_ptr<base::DictionaryValue> caps_value = caps.ToValue(); |
| + scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| + v8::Handle<v8::Value> caps_v8 = converter->ToV8Value( |
| + caps_value.get(), context()->v8_context()); |
| + context()->CallFunction(v8::Handle<v8::Function>::Cast(args[1]), 1, |
| + &caps_v8); |
| } |
| void WebRtcNativeHandler::StartCastSendTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(2, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
| + CHECK(args[1]->IsObject()); |
| + |
| + int transport_id = static_cast<int>(args[0]->ToInt32()->Value()); |
| + CastSendTransport* transport = GetSendTransport(transport_id); |
| + if (!transport) |
| + return; |
| + |
| + scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| + scoped_ptr<Value> params_value( |
| + converter->FromV8Value(args[1], context()->v8_context())); |
| + if (!params_value) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kUnableToConvertParams))); |
| + return; |
| + } |
| + scoped_ptr<RtpParams> params = RtpParams::FromValue(*params_value); |
| + if (!params) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kInvalidRtpParams))); |
| + return; |
| + } |
| + |
| + CastRtpCaps cast_params; |
| + if (!ToCastRtpParams(*params, &cast_params)) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kUnableToConvertParams))); |
| + return; |
| + } |
| + transport->Start(cast_params); |
| } |
| void WebRtcNativeHandler::StopCastSendTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(1, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
| + |
| + int transport_id = static_cast<int>(args[0]->ToInt32()->Value()); |
| + CastSendTransport* transport = GetSendTransport(transport_id); |
| + if (!transport) |
| + return; |
| + transport->Stop(); |
| } |
| void WebRtcNativeHandler::CreateCastUdpTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(1, args.Length()); |
| + CHECK(args[0]->IsFunction()); |
| + |
| + // TODO(hclam): Fill in |create_info| properly. We might have to |
| + // call the callback asynchronously after the port is allocated. |
| + CreateInfo create_info; |
| + create_info.transport_id = last_transport_id_++; |
|
scherkus (not reviewing)
2013/10/29 17:38:17
do we need to initialize create_info.params in any
Alpha Left Google
2013/10/29 19:52:18
It will initialized with 0s which is appropriate f
|
| + udp_transport_map_[create_info.transport_id] = |
| + linked_ptr<CastUdpTransport>(new CastUdpTransport()); |
| + |
| + scoped_ptr<base::DictionaryValue> create_info_value = create_info.ToValue(); |
| + scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| + v8::Handle<v8::Value> create_info_v8 = converter->ToV8Value( |
| + create_info_value.get(), context()->v8_context()); |
| + context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]), 1, |
| + &create_info_v8); |
| +} |
| + |
| +void WebRtcNativeHandler::DestroyCastUdpTransport( |
| + const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + CHECK_EQ(1, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
|
justinlin
2013/10/29 18:22:29
I don't think you want to CHECK these. They're use
Alpha Left Google
2013/10/29 19:52:18
This seems to be the style used for the extension
|
| + |
| + int transport_id = static_cast<int>(args[0]->ToInt32()->Value()); |
| + CastUdpTransport* transport = GetUdpTransport(transport_id); |
| + if (!transport) |
| + return; |
| + udp_transport_map_.erase(transport_id); |
| } |
| void WebRtcNativeHandler::StartCastUdpTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(2, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
|
scherkus (not reviewing)
2013/10/29 17:38:17
what about args[1]?
Alpha Left Google
2013/10/29 19:52:18
Checked for IsObject().
|
| + |
| + int transport_id = static_cast<int>(args[0]->ToInt32()->Value()); |
| + CastUdpTransport* transport = GetUdpTransport(transport_id); |
| + if (!transport) |
| + return; |
| + |
| + scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| + scoped_ptr<Value> udp_params_value( |
| + converter->FromV8Value(args[1], context()->v8_context())); |
| + if (!udp_params_value) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kUnableToConvertArgs))); |
| + return; |
| + } |
| + scoped_ptr<UdpParams> udp_params = UdpParams::FromValue(*udp_params_value); |
| + if (!udp_params) { |
| + v8::ThrowException(v8::Exception::TypeError(v8::String::New( |
| + kInvalidUdpParams))); |
| + return; |
| + } |
| + transport->Start(net::HostPortPair(udp_params->address, udp_params->port)); |
| } |
| void WebRtcNativeHandler::StopCastUdpTransport( |
| const v8::FunctionCallbackInfo<v8::Value>& args) { |
| - NOTIMPLEMENTED(); |
| + CHECK_EQ(1, args.Length()); |
| + CHECK(args[0]->IsInt32()); |
| + |
| + int transport_id = static_cast<int>(args[0]->ToInt32()->Value()); |
| + CastUdpTransport* transport = GetUdpTransport(transport_id); |
| + if (!transport) |
| + return; |
| + transport->Stop(); |
| +} |
| + |
| +CastSendTransport* WebRtcNativeHandler::GetSendTransport( |
| + int transport_id) const { |
| + SendTransportMap::const_iterator iter = send_transport_map_.find( |
| + transport_id); |
| + if (iter != send_transport_map_.end()) |
| + return iter->second.get(); |
| + v8::ThrowException(v8::Exception::RangeError(v8::String::New( |
| + kSendTransportNotFound))); |
| + return NULL; |
| +} |
| + |
| +CastUdpTransport* WebRtcNativeHandler::GetUdpTransport( |
| + int transport_id) const { |
| + UdpTransportMap::const_iterator iter = udp_transport_map_.find( |
| + transport_id); |
| + if (iter != udp_transport_map_.end()) |
| + return iter->second.get(); |
| + v8::ThrowException(v8::Exception::RangeError(v8::String::New( |
| + kUdpTransportNotFound))); |
| + return NULL; |
| } |
| } // namespace extensions |