OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/extensions/cast_streaming_native_handler.h" | 5 #include "chrome/renderer/extensions/cast_streaming_native_handler.h" |
6 | 6 |
7 #include <functional> | 7 #include <functional> |
8 | 8 |
| 9 #include "base/base64.h" |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
11 #include "chrome/common/extensions/api/cast_streaming_rtp_stream.h" | 12 #include "chrome/common/extensions/api/cast_streaming_rtp_stream.h" |
12 #include "chrome/common/extensions/api/cast_streaming_udp_transport.h" | 13 #include "chrome/common/extensions/api/cast_streaming_udp_transport.h" |
13 #include "chrome/renderer/extensions/chrome_v8_context.h" | 14 #include "chrome/renderer/extensions/chrome_v8_context.h" |
14 #include "chrome/renderer/media/cast_rtp_stream.h" | 15 #include "chrome/renderer/media/cast_rtp_stream.h" |
15 #include "chrome/renderer/media/cast_session.h" | 16 #include "chrome/renderer/media/cast_session.h" |
16 #include "chrome/renderer/media/cast_udp_transport.h" | 17 #include "chrome/renderer/media/cast_udp_transport.h" |
17 #include "content/public/renderer/v8_value_converter.h" | 18 #include "content/public/renderer/v8_value_converter.h" |
18 #include "net/base/host_port_pair.h" | 19 #include "net/base/host_port_pair.h" |
19 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 20 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
20 #include "third_party/WebKit/public/web/WebDOMMediaStreamTrack.h" | 21 #include "third_party/WebKit/public/web/WebDOMMediaStreamTrack.h" |
21 | 22 |
22 using content::V8ValueConverter; | 23 using content::V8ValueConverter; |
23 | 24 |
24 // Extension types. | 25 // Extension types. |
25 using extensions::api::cast_streaming_rtp_stream::CodecSpecificParams; | 26 using extensions::api::cast_streaming_rtp_stream::CodecSpecificParams; |
26 using extensions::api::cast_streaming_rtp_stream::RtpCaps; | 27 using extensions::api::cast_streaming_rtp_stream::RtpCaps; |
27 using extensions::api::cast_streaming_rtp_stream::RtpParams; | 28 using extensions::api::cast_streaming_rtp_stream::RtpParams; |
28 using extensions::api::cast_streaming_rtp_stream::RtpPayloadParams; | 29 using extensions::api::cast_streaming_rtp_stream::RtpPayloadParams; |
29 using extensions::api::cast_streaming_udp_transport::UdpParams; | 30 using extensions::api::cast_streaming_udp_transport::UdpParams; |
30 | 31 |
31 namespace extensions { | 32 namespace extensions { |
32 | 33 |
33 namespace { | 34 namespace { |
34 const char kRtpStreamNotFound[] = "The RTP stream cannot be found"; | 35 const char kRtpStreamNotFound[] = "The RTP stream cannot be found"; |
35 const char kUdpTransportNotFound[] = "The UDP transport cannot be found"; | 36 const char kUdpTransportNotFound[] = "The UDP transport cannot be found"; |
36 const char kInvalidUdpParams[] = "Invalid UDP params"; | 37 const char kInvalidUdpParams[] = "Invalid UDP params"; |
37 const char kInvalidRtpParams[] = "Invalid value for RTP params"; | 38 const char kInvalidRtpParams[] = "Invalid value for RTP params"; |
| 39 const char kInvalidAesKey[] = "Invalid value for AES key"; |
| 40 const char kInvalidAesIvMask[] = "Invalid value for AES IV mask"; |
38 const char kUnableToConvertArgs[] = "Unable to convert arguments"; | 41 const char kUnableToConvertArgs[] = "Unable to convert arguments"; |
39 const char kUnableToConvertParams[] = "Unable to convert params"; | 42 const char kUnableToConvertParams[] = "Unable to convert params"; |
40 | 43 |
41 // These helper methods are used to convert between Extension API | 44 // These helper methods are used to convert between Extension API |
42 // types and Cast types. | 45 // types and Cast types. |
43 void ToCastCodecSpecificParams(const CodecSpecificParams& ext_params, | 46 void ToCastCodecSpecificParams(const CodecSpecificParams& ext_params, |
44 CastCodecSpecificParams* cast_params) { | 47 CastCodecSpecificParams* cast_params) { |
45 cast_params->key = ext_params.key; | 48 cast_params->key = ext_params.key; |
46 cast_params->value = ext_params.value; | 49 cast_params->value = ext_params.value; |
47 } | 50 } |
48 | 51 |
49 void FromCastCodecSpecificParams(const CastCodecSpecificParams& cast_params, | 52 void FromCastCodecSpecificParams(const CastCodecSpecificParams& cast_params, |
50 CodecSpecificParams* ext_params) { | 53 CodecSpecificParams* ext_params) { |
51 ext_params->key = cast_params.key; | 54 ext_params->key = cast_params.key; |
52 ext_params->value = cast_params.value; | 55 ext_params->value = cast_params.value; |
53 } | 56 } |
54 | 57 |
55 void ToCastRtpPayloadParams(const RtpPayloadParams& ext_params, | 58 bool ToCastRtpPayloadParamsOrThrow(v8::Isolate* isolate, |
56 CastRtpPayloadParams* cast_params) { | 59 const RtpPayloadParams& ext_params, |
| 60 CastRtpPayloadParams* cast_params) { |
57 cast_params->payload_type = ext_params.payload_type; | 61 cast_params->payload_type = ext_params.payload_type; |
58 cast_params->codec_name = ext_params.codec_name; | 62 cast_params->codec_name = ext_params.codec_name; |
59 cast_params->ssrc = ext_params.ssrc ? *ext_params.ssrc : 0; | 63 cast_params->ssrc = ext_params.ssrc ? *ext_params.ssrc : 0; |
60 cast_params->feedback_ssrc = | 64 cast_params->feedback_ssrc = |
61 ext_params.feedback_ssrc ? *ext_params.feedback_ssrc : 0; | 65 ext_params.feedback_ssrc ? *ext_params.feedback_ssrc : 0; |
62 cast_params->clock_rate = ext_params.clock_rate ? *ext_params.clock_rate : 0; | 66 cast_params->clock_rate = ext_params.clock_rate ? *ext_params.clock_rate : 0; |
63 cast_params->min_bitrate = | 67 cast_params->min_bitrate = |
64 ext_params.min_bitrate ? *ext_params.min_bitrate : 0; | 68 ext_params.min_bitrate ? *ext_params.min_bitrate : 0; |
65 cast_params->max_bitrate = | 69 cast_params->max_bitrate = |
66 ext_params.max_bitrate ? *ext_params.max_bitrate : 0; | 70 ext_params.max_bitrate ? *ext_params.max_bitrate : 0; |
67 cast_params->channels = ext_params.channels ? *ext_params.channels : 0; | 71 cast_params->channels = ext_params.channels ? *ext_params.channels : 0; |
68 cast_params->width = ext_params.width ? *ext_params.width : 0; | 72 cast_params->width = ext_params.width ? *ext_params.width : 0; |
69 cast_params->height = ext_params.height ? *ext_params.height : 0; | 73 cast_params->height = ext_params.height ? *ext_params.height : 0; |
| 74 if (ext_params.aes_key && |
| 75 !base::Base64Decode(*ext_params.aes_key, &cast_params->aes_key)) { |
| 76 isolate->ThrowException(v8::Exception::Error( |
| 77 v8::String::NewFromUtf8(isolate, kInvalidAesKey))); |
| 78 return false; |
| 79 } |
| 80 if (ext_params.aes_iv_mask && |
| 81 !base::Base64Decode(*ext_params.aes_iv_mask, |
| 82 &cast_params->aes_iv_mask)) { |
| 83 isolate->ThrowException(v8::Exception::Error( |
| 84 v8::String::NewFromUtf8(isolate, kInvalidAesIvMask))); |
| 85 return false; |
| 86 } |
70 for (size_t i = 0; i < ext_params.codec_specific_params.size(); ++i) { | 87 for (size_t i = 0; i < ext_params.codec_specific_params.size(); ++i) { |
71 CastCodecSpecificParams cast_codec_params; | 88 CastCodecSpecificParams cast_codec_params; |
72 ToCastCodecSpecificParams(*ext_params.codec_specific_params[i], | 89 ToCastCodecSpecificParams(*ext_params.codec_specific_params[i], |
73 &cast_codec_params); | 90 &cast_codec_params); |
74 cast_params->codec_specific_params.push_back(cast_codec_params); | 91 cast_params->codec_specific_params.push_back(cast_codec_params); |
75 } | 92 } |
| 93 return true; |
76 } | 94 } |
77 | 95 |
78 void FromCastRtpPayloadParams(const CastRtpPayloadParams& cast_params, | 96 void FromCastRtpPayloadParams(const CastRtpPayloadParams& cast_params, |
79 RtpPayloadParams* ext_params) { | 97 RtpPayloadParams* ext_params) { |
80 ext_params->payload_type = cast_params.payload_type; | 98 ext_params->payload_type = cast_params.payload_type; |
81 ext_params->codec_name = cast_params.codec_name; | 99 ext_params->codec_name = cast_params.codec_name; |
82 if (cast_params.ssrc) | 100 if (cast_params.ssrc) |
83 ext_params->ssrc.reset(new int(cast_params.ssrc)); | 101 ext_params->ssrc.reset(new int(cast_params.ssrc)); |
84 if (cast_params.feedback_ssrc) | 102 if (cast_params.feedback_ssrc) |
85 ext_params->feedback_ssrc.reset(new int(cast_params.feedback_ssrc)); | 103 ext_params->feedback_ssrc.reset(new int(cast_params.feedback_ssrc)); |
(...skipping 21 matching lines...) Expand all Loading... |
107 void FromCastRtpCaps(const CastRtpCaps& cast_caps, RtpCaps* ext_caps) { | 125 void FromCastRtpCaps(const CastRtpCaps& cast_caps, RtpCaps* ext_caps) { |
108 std::copy(cast_caps.rtcp_features.begin(), cast_caps.rtcp_features.end(), | 126 std::copy(cast_caps.rtcp_features.begin(), cast_caps.rtcp_features.end(), |
109 ext_caps->rtcp_features.begin()); | 127 ext_caps->rtcp_features.begin()); |
110 for (size_t i = 0; i < cast_caps.payloads.size(); ++i) { | 128 for (size_t i = 0; i < cast_caps.payloads.size(); ++i) { |
111 linked_ptr<RtpPayloadParams> ext_payload_params(new RtpPayloadParams()); | 129 linked_ptr<RtpPayloadParams> ext_payload_params(new RtpPayloadParams()); |
112 FromCastRtpPayloadParams(cast_caps.payloads[i], ext_payload_params.get()); | 130 FromCastRtpPayloadParams(cast_caps.payloads[i], ext_payload_params.get()); |
113 ext_caps->payloads.push_back(ext_payload_params); | 131 ext_caps->payloads.push_back(ext_payload_params); |
114 } | 132 } |
115 } | 133 } |
116 | 134 |
117 void ToCastRtpParams(const RtpParams& ext_params, CastRtpParams* cast_params) { | 135 bool ToCastRtpParamsOrThrow(v8::Isolate* isolate, |
| 136 const RtpParams& ext_params, |
| 137 CastRtpParams* cast_params) { |
118 std::copy(ext_params.rtcp_features.begin(), ext_params.rtcp_features.end(), | 138 std::copy(ext_params.rtcp_features.begin(), ext_params.rtcp_features.end(), |
119 cast_params->rtcp_features.begin()); | 139 cast_params->rtcp_features.begin()); |
120 for (size_t i = 0; i < ext_params.payloads.size(); ++i) { | 140 for (size_t i = 0; i < ext_params.payloads.size(); ++i) { |
121 CastRtpPayloadParams cast_payload_params; | 141 CastRtpPayloadParams cast_payload_params; |
122 ToCastRtpPayloadParams(*ext_params.payloads[i], &cast_payload_params); | 142 if (!ToCastRtpPayloadParamsOrThrow(isolate, |
| 143 *ext_params.payloads[i], |
| 144 &cast_payload_params)) { |
| 145 return false; |
| 146 } |
123 cast_params->payloads.push_back(cast_payload_params); | 147 cast_params->payloads.push_back(cast_payload_params); |
124 } | 148 } |
| 149 return true; |
125 } | 150 } |
126 | 151 |
127 } // namespace | 152 } // namespace |
128 | 153 |
129 CastStreamingNativeHandler::CastStreamingNativeHandler(ChromeV8Context* context) | 154 CastStreamingNativeHandler::CastStreamingNativeHandler(ChromeV8Context* context) |
130 : ObjectBackedNativeHandler(context), | 155 : ObjectBackedNativeHandler(context), |
131 last_transport_id_(0), | 156 last_transport_id_(0), |
132 weak_factory_(this) { | 157 weak_factory_(this) { |
133 RouteFunction("CreateSession", | 158 RouteFunction("CreateSession", |
134 base::Bind(&CastStreamingNativeHandler::CreateCastSession, | 159 base::Bind(&CastStreamingNativeHandler::CreateCastSession, |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 return; | 295 return; |
271 } | 296 } |
272 scoped_ptr<RtpParams> params = RtpParams::FromValue(*params_value); | 297 scoped_ptr<RtpParams> params = RtpParams::FromValue(*params_value); |
273 if (!params) { | 298 if (!params) { |
274 args.GetIsolate()->ThrowException(v8::Exception::TypeError( | 299 args.GetIsolate()->ThrowException(v8::Exception::TypeError( |
275 v8::String::NewFromUtf8(args.GetIsolate(), kInvalidRtpParams))); | 300 v8::String::NewFromUtf8(args.GetIsolate(), kInvalidRtpParams))); |
276 return; | 301 return; |
277 } | 302 } |
278 | 303 |
279 CastRtpCaps cast_params; | 304 CastRtpCaps cast_params; |
280 ToCastRtpParams(*params, &cast_params); | 305 v8::Isolate* isolate = context()->v8_context()->GetIsolate(); |
| 306 if (!ToCastRtpParamsOrThrow(isolate, *params, &cast_params)) |
| 307 return; |
281 transport->Start(cast_params); | 308 transport->Start(cast_params); |
282 } | 309 } |
283 | 310 |
284 void CastStreamingNativeHandler::StopCastRtpStream( | 311 void CastStreamingNativeHandler::StopCastRtpStream( |
285 const v8::FunctionCallbackInfo<v8::Value>& args) { | 312 const v8::FunctionCallbackInfo<v8::Value>& args) { |
286 CHECK_EQ(1, args.Length()); | 313 CHECK_EQ(1, args.Length()); |
287 CHECK(args[0]->IsInt32()); | 314 CHECK(args[0]->IsInt32()); |
288 | 315 |
289 const int transport_id = args[0]->ToInt32()->Value(); | 316 const int transport_id = args[0]->ToInt32()->Value(); |
290 CastRtpStream* transport = GetRtpStreamOrThrow(transport_id); | 317 CastRtpStream* transport = GetRtpStreamOrThrow(transport_id); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 transport_id); | 383 transport_id); |
357 if (iter != udp_transport_map_.end()) | 384 if (iter != udp_transport_map_.end()) |
358 return iter->second.get(); | 385 return iter->second.get(); |
359 v8::Isolate* isolate = context()->v8_context()->GetIsolate(); | 386 v8::Isolate* isolate = context()->v8_context()->GetIsolate(); |
360 isolate->ThrowException(v8::Exception::RangeError( | 387 isolate->ThrowException(v8::Exception::RangeError( |
361 v8::String::NewFromUtf8(isolate, kUdpTransportNotFound))); | 388 v8::String::NewFromUtf8(isolate, kUdpTransportNotFound))); |
362 return NULL; | 389 return NULL; |
363 } | 390 } |
364 | 391 |
365 } // namespace extensions | 392 } // namespace extensions |
OLD | NEW |