Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: webkit/plugins/ppapi/ppb_transport_impl.cc

Issue 10454058: Remove PPB_Transport_Dev API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/plugins/ppapi/ppb_transport_impl.h"
6
7 #include "base/message_loop.h"
8 #include "base/string_util.h"
9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h"
11 #include "net/base/net_util.h"
12 #include "net/socket/socket.h"
13 #include "ppapi/c/dev/ppb_transport_dev.h"
14 #include "ppapi/c/pp_completion_callback.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/shared_impl/callback_tracker.h"
17 #include "ppapi/shared_impl/ppapi_globals.h"
18 #include "ppapi/shared_impl/var.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
22 #include "webkit/plugins/ppapi/common.h"
23 #include "webkit/plugins/ppapi/plugin_module.h"
24 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
25 #include "webkit/plugins/ppapi/resource_helper.h"
26
27 using ppapi::StringVar;
28 using ppapi::thunk::PPB_Transport_API;
29 using ppapi::TrackedCallback;
30 using webkit_glue::P2PTransport;
31
32 namespace webkit {
33 namespace ppapi {
34
35 namespace {
36
37 const char kUdpProtocolName[] = "udp";
38 const char kTcpProtocolName[] = "tcp";
39
40 const int kMinBufferSize = 1024;
41 const int kMaxBufferSize = 1024 * 1024;
42 const int kMinAckDelay = 10;
43 const int kMaxAckDelay = 1000;
44
45 int MapNetError(int result) {
46 if (result > 0)
47 return result;
48
49 switch (result) {
50 case net::OK:
51 return PP_OK;
52 case net::ERR_IO_PENDING:
53 return PP_OK_COMPLETIONPENDING;
54 case net::ERR_INVALID_ARGUMENT:
55 return PP_ERROR_BADARGUMENT;
56 default:
57 return PP_ERROR_FAILED;
58 }
59 }
60
61 WebKit::WebFrame* GetFrameForResource(const ::ppapi::Resource* resource) {
62 PluginInstance* plugin_instance =
63 ResourceHelper::GetPluginInstance(resource);
64 if (!plugin_instance)
65 return NULL;
66 return plugin_instance->container()->element().document().frame();
67 }
68
69 } // namespace
70
71 PPB_Transport_Impl::PPB_Transport_Impl(PP_Instance instance)
72 : Resource(::ppapi::OBJECT_IS_IMPL, instance),
73 type_(PP_TRANSPORTTYPE_DATAGRAM),
74 started_(false),
75 writable_(false) {
76 }
77
78 PPB_Transport_Impl::~PPB_Transport_Impl() {
79 }
80
81 // static
82 PP_Resource PPB_Transport_Impl::Create(PP_Instance instance,
83 const char* name,
84 PP_TransportType type) {
85 scoped_refptr<PPB_Transport_Impl> t(new PPB_Transport_Impl(instance));
86 if (!t->Init(name, type))
87 return 0;
88 return t->GetReference();
89 }
90
91 PPB_Transport_API* PPB_Transport_Impl::AsPPB_Transport_API() {
92 return this;
93 }
94
95 bool PPB_Transport_Impl::Init(const char* name, PP_TransportType type) {
96 name_ = name;
97
98 if (type != PP_TRANSPORTTYPE_DATAGRAM && type != PP_TRANSPORTTYPE_STREAM) {
99 LOG(WARNING) << "Unknown transport type: " << type;
100 return false;
101 }
102 type_ = type;
103
104 PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
105 if (!plugin_delegate)
106 return false;
107 p2p_transport_.reset(plugin_delegate->CreateP2PTransport());
108 return p2p_transport_.get() != NULL;
109 }
110
111 PP_Bool PPB_Transport_Impl::IsWritable() {
112 if (!p2p_transport_.get())
113 return PP_FALSE;
114
115 return PP_FromBool(writable_);
116 }
117
118 int32_t PPB_Transport_Impl::SetProperty(PP_TransportProperty property,
119 PP_Var value) {
120 // SetProperty() may be called only before Connect().
121 if (started_)
122 return PP_ERROR_FAILED;
123
124 switch (property) {
125 case PP_TRANSPORTPROPERTY_STUN_SERVER: {
126 StringVar* value_str = StringVar::FromPPVar(value);
127 if (!value_str)
128 return PP_ERROR_BADARGUMENT;
129 if (!net::ParseHostAndPort(value_str->value(), &config_.stun_server,
130 &config_.stun_server_port)) {
131 return PP_ERROR_BADARGUMENT;
132 }
133 break;
134 }
135
136 case PP_TRANSPORTPROPERTY_RELAY_SERVER: {
137 StringVar* value_str = StringVar::FromPPVar(value);
138 if (!value_str)
139 return PP_ERROR_BADARGUMENT;
140 if (!net::ParseHostAndPort(value_str->value(), &config_.relay_server,
141 &config_.relay_server_port)) {
142 return PP_ERROR_BADARGUMENT;
143 }
144 break;
145 }
146
147 case PP_TRANSPORTPROPERTY_RELAY_USERNAME: {
148 StringVar* value_str = StringVar::FromPPVar(value);
149 if (!value_str)
150 return PP_ERROR_BADARGUMENT;
151 config_.relay_username = value_str->value();
152 break;
153 }
154
155 case PP_TRANSPORTPROPERTY_RELAY_PASSWORD: {
156 StringVar* value_str = StringVar::FromPPVar(value);
157 if (!value_str)
158 return PP_ERROR_BADARGUMENT;
159 config_.relay_password = value_str->value();
160 break;
161 }
162
163 case PP_TRANSPORTPROPERTY_RELAY_MODE: {
164 switch (value.value.as_int) {
165 case PP_TRANSPORTRELAYMODE_TURN:
166 config_.legacy_relay = false;
167 break;
168 case PP_TRANSPORTRELAYMODE_GOOGLE:
169 config_.legacy_relay = true;
170 break;
171 default:
172 return PP_ERROR_BADARGUMENT;
173 }
174 break;
175 }
176
177 case PP_TRANSPORTPROPERTY_TCP_RECEIVE_WINDOW: {
178 if (type_ != PP_TRANSPORTTYPE_STREAM)
179 return PP_ERROR_BADARGUMENT;
180
181 int32_t int_value = value.value.as_int;
182 if (value.type != PP_VARTYPE_INT32 || int_value < kMinBufferSize ||
183 int_value > kMaxBufferSize) {
184 return PP_ERROR_BADARGUMENT;
185 }
186 config_.tcp_receive_window = int_value;
187 break;
188 }
189
190 case PP_TRANSPORTPROPERTY_TCP_SEND_WINDOW: {
191 if (type_ != PP_TRANSPORTTYPE_STREAM)
192 return PP_ERROR_BADARGUMENT;
193
194 int32_t int_value = value.value.as_int;
195 if (value.type != PP_VARTYPE_INT32 || int_value < kMinBufferSize ||
196 int_value > kMaxBufferSize) {
197 return PP_ERROR_BADARGUMENT;
198 }
199 config_.tcp_send_window = int_value;
200 break;
201 }
202
203 case PP_TRANSPORTPROPERTY_TCP_NO_DELAY: {
204 if (type_ != PP_TRANSPORTTYPE_STREAM)
205 return PP_ERROR_BADARGUMENT;
206
207 if (value.type != PP_VARTYPE_BOOL)
208 return PP_ERROR_BADARGUMENT;
209 config_.tcp_no_delay = PP_ToBool(value.value.as_bool);
210 break;
211 }
212
213 case PP_TRANSPORTPROPERTY_TCP_ACK_DELAY: {
214 if (type_ != PP_TRANSPORTTYPE_STREAM)
215 return PP_ERROR_BADARGUMENT;
216
217 int32_t int_value = value.value.as_int;
218 if (value.type != PP_VARTYPE_INT32 || int_value < kMinAckDelay ||
219 int_value > kMaxAckDelay) {
220 return PP_ERROR_BADARGUMENT;
221 }
222 config_.tcp_ack_delay_ms = int_value;
223 break;
224 }
225
226 case PP_TRANSPORTPROPERTY_DISABLE_TCP_TRANSPORT: {
227 if (value.type != PP_VARTYPE_BOOL)
228 return PP_ERROR_BADARGUMENT;
229 config_.disable_tcp_transport = PP_ToBool(value.value.as_bool);
230 break;
231 }
232
233 default:
234 return PP_ERROR_BADARGUMENT;
235 }
236
237 return PP_OK;
238 }
239
240 int32_t PPB_Transport_Impl::Connect(PP_CompletionCallback callback) {
241 if (!callback.func)
242 return PP_ERROR_BLOCKS_MAIN_THREAD;
243 if (!p2p_transport_.get())
244 return PP_ERROR_FAILED;
245
246 // Connect() has already been called.
247 if (started_)
248 return PP_ERROR_INPROGRESS;
249
250 P2PTransport::Protocol protocol = (type_ == PP_TRANSPORTTYPE_STREAM) ?
251 P2PTransport::PROTOCOL_TCP : P2PTransport::PROTOCOL_UDP;
252
253 if (!p2p_transport_->Init(
254 GetFrameForResource(this), name_, protocol, config_, this)) {
255 return PP_ERROR_FAILED;
256 }
257
258 started_ = true;
259
260 PluginModule* plugin_module = ResourceHelper::GetPluginModule(this);
261 if (!plugin_module)
262 return PP_ERROR_FAILED;
263
264 connect_callback_ = new TrackedCallback(this, callback);
265 return PP_OK_COMPLETIONPENDING;
266 }
267
268 int32_t PPB_Transport_Impl::GetNextAddress(PP_Var* address,
269 PP_CompletionCallback callback) {
270 if (!callback.func)
271 return PP_ERROR_BLOCKS_MAIN_THREAD;
272 if (!p2p_transport_.get())
273 return PP_ERROR_FAILED;
274
275 if (TrackedCallback::IsPending(next_address_callback_))
276 return PP_ERROR_INPROGRESS;
277
278 PluginModule* plugin_module = ResourceHelper::GetPluginModule(this);
279 if (!plugin_module)
280 return PP_ERROR_FAILED;
281
282 if (!local_candidates_.empty()) {
283 *address = StringVar::StringToPPVar(local_candidates_.front());
284 local_candidates_.pop_front();
285 return PP_OK;
286 }
287
288 next_address_callback_ = new TrackedCallback(this, callback);
289 return PP_OK_COMPLETIONPENDING;
290 }
291
292 int32_t PPB_Transport_Impl::ReceiveRemoteAddress(PP_Var address) {
293 if (!p2p_transport_.get())
294 return PP_ERROR_FAILED;
295
296 StringVar* address_str = StringVar::FromPPVar(address);
297 if (!address_str)
298 return PP_ERROR_BADARGUMENT;
299
300 return p2p_transport_->AddRemoteCandidate(address_str->value()) ?
301 PP_OK : PP_ERROR_FAILED;
302 }
303
304 int32_t PPB_Transport_Impl::Recv(void* data, uint32_t len,
305 PP_CompletionCallback callback) {
306 if (!callback.func)
307 return PP_ERROR_BLOCKS_MAIN_THREAD;
308 if (!p2p_transport_.get())
309 return PP_ERROR_FAILED;
310
311 if (TrackedCallback::IsPending(recv_callback_))
312 return PP_ERROR_INPROGRESS;
313
314 net::Socket* channel = p2p_transport_->GetChannel();
315 if (!channel)
316 return PP_ERROR_FAILED;
317
318 PluginModule* plugin_module = ResourceHelper::GetPluginModule(this);
319 if (!plugin_module)
320 return PP_ERROR_FAILED;
321
322 scoped_refptr<net::IOBuffer> buffer =
323 new net::WrappedIOBuffer(static_cast<const char*>(data));
324 int result = MapNetError(
325 channel->Read(buffer, len, base::Bind(&PPB_Transport_Impl::OnRead,
326 base::Unretained(this))));
327 if (result == PP_OK_COMPLETIONPENDING)
328 recv_callback_ = new TrackedCallback(this, callback);
329
330 return result;
331 }
332
333 int32_t PPB_Transport_Impl::Send(const void* data, uint32_t len,
334 PP_CompletionCallback callback) {
335 if (!callback.func)
336 return PP_ERROR_BLOCKS_MAIN_THREAD;
337 if (!p2p_transport_.get())
338 return PP_ERROR_FAILED;
339
340 if (TrackedCallback::IsPending(send_callback_))
341 return PP_ERROR_INPROGRESS;
342
343 net::Socket* channel = p2p_transport_->GetChannel();
344 if (!channel)
345 return PP_ERROR_FAILED;
346
347 PluginModule* plugin_module = ResourceHelper::GetPluginModule(this);
348 if (!plugin_module)
349 return PP_ERROR_FAILED;
350
351 scoped_refptr<net::IOBuffer> buffer =
352 new net::WrappedIOBuffer(static_cast<const char*>(data));
353 int result = MapNetError(
354 channel->Write(buffer, len, base::Bind(&PPB_Transport_Impl::OnWritten,
355 base::Unretained(this))));
356 if (result == PP_OK_COMPLETIONPENDING)
357 send_callback_ = new TrackedCallback(this, callback);
358
359 return result;
360 }
361
362 int32_t PPB_Transport_Impl::Close() {
363 if (!p2p_transport_.get())
364 return PP_ERROR_FAILED;
365
366 p2p_transport_.reset();
367
368 ::ppapi::PpapiGlobals::Get()->GetCallbackTrackerForInstance(
369 pp_instance())->PostAbortForResource(pp_resource());
370 return PP_OK;
371 }
372
373 void PPB_Transport_Impl::OnCandidateReady(const std::string& address) {
374 // Store the candidate first before calling the callback.
375 local_candidates_.push_back(address);
376
377 if (TrackedCallback::IsPending(next_address_callback_))
378 TrackedCallback::ClearAndRun(&next_address_callback_, PP_OK);
379 }
380
381 void PPB_Transport_Impl::OnStateChange(webkit_glue::P2PTransport::State state) {
382 writable_ = (state | webkit_glue::P2PTransport::STATE_WRITABLE) != 0;
383 if (writable_ && TrackedCallback::IsPending(connect_callback_))
384 TrackedCallback::ClearAndRun(&connect_callback_, PP_OK);
385 }
386
387 void PPB_Transport_Impl::OnError(int error) {
388 writable_ = false;
389 if (TrackedCallback::IsPending(connect_callback_))
390 TrackedCallback::ClearAndRun(&connect_callback_, PP_ERROR_FAILED);
391 }
392
393 void PPB_Transport_Impl::OnRead(int result) {
394 DCHECK(TrackedCallback::IsPending(recv_callback_));
395 TrackedCallback::ClearAndRun(&recv_callback_, MapNetError(result));
396 }
397
398 void PPB_Transport_Impl::OnWritten(int result) {
399 DCHECK(TrackedCallback::IsPending(send_callback_));
400 TrackedCallback::ClearAndRun(&send_callback_, MapNetError(result));
401 }
402
403 } // namespace ppapi
404 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/ppb_transport_impl.h ('k') | webkit/plugins/ppapi/resource_creation_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698