OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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 "remoting/protocol/pepper_transport_socket_adaptor.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "net/base/io_buffer.h" | |
9 #include "net/base/net_errors.h" | |
10 #include "ppapi/c/pp_errors.h" | |
11 #include "ppapi/cpp/dev/transport_dev.h" | |
12 #include "ppapi/cpp/var.h" | |
13 | |
14 namespace remoting { | |
15 namespace protocol { | |
16 | |
17 namespace { | |
18 | |
19 const char kUdpProtocol[] = "udp"; | |
20 const char kTcpProtocol[] = "tcp"; | |
21 | |
22 // Maps value returned by Recv() and Send() Pepper methods to net::Error. | |
23 int PPErrorToNetError(int result) { | |
24 if (result > 0) | |
25 return result; | |
26 | |
27 switch (result) { | |
28 case PP_OK: | |
29 return net::OK; | |
30 case PP_OK_COMPLETIONPENDING: | |
31 return net::ERR_IO_PENDING; | |
32 default: | |
33 return net::ERR_FAILED; | |
34 } | |
35 } | |
36 | |
37 } // namespace | |
38 | |
39 PepperTransportSocketAdaptor::PepperTransportSocketAdaptor( | |
40 pp::Instance* pp_instance, | |
41 const std::string& name, | |
42 ChannelType type, | |
43 Observer* observer) | |
44 : name_(name), | |
45 observer_(observer), | |
46 connected_(false), | |
47 get_address_pending_(false), | |
48 read_callback_(NULL), | |
49 write_callback_(NULL) { | |
50 callback_factory_.Initialize(this); | |
51 transport_.reset(new pp::Transport_Dev( | |
52 pp_instance, name_.c_str(), | |
53 type == STREAM ? kTcpProtocol : kUdpProtocol)); | |
Wez
2011/08/02 23:13:24
See previous comments regarding stream vs datagram
Sergey Ulanov
2011/08/03 00:02:16
Done.
| |
54 } | |
55 | |
56 PepperTransportSocketAdaptor::~PepperTransportSocketAdaptor() { | |
57 observer_->OnChannelDeleted(); | |
58 } | |
59 | |
60 void PepperTransportSocketAdaptor::AddRemoteCandidate( | |
61 const std::string& candidate) { | |
62 DCHECK(CalledOnValidThread()); | |
63 transport_->ReceiveRemoteAddress(candidate); | |
64 } | |
65 | |
66 int PepperTransportSocketAdaptor::Read(net::IOBuffer* buf, int buf_len, | |
67 net::CompletionCallback* callback) { | |
68 DCHECK(CalledOnValidThread()); | |
69 DCHECK(!read_callback_); | |
70 DCHECK(!read_buffer_); | |
71 | |
72 int result = PPErrorToNetError(transport_->Recv( | |
73 buf->data(), buf_len, | |
74 callback_factory_.NewOptionalCallback( | |
75 &PepperTransportSocketAdaptor::OnRead))); | |
Wez
2011/08/02 23:13:24
Is there any need for this to be an optional callb
Sergey Ulanov
2011/08/03 00:02:16
Callbacks for the upper layer (Socket interface) a
Wez
2011/08/03 00:34:48
We could verify that calling-code copes with optio
Sergey Ulanov
2011/08/03 00:43:37
Yes, but in ether case required callbacks will not
| |
76 | |
77 if (result == net::ERR_IO_PENDING) { | |
78 read_callback_ = callback; | |
79 read_buffer_ = buf; | |
80 } | |
81 | |
82 return result; | |
83 } | |
84 | |
85 int PepperTransportSocketAdaptor::Write(net::IOBuffer* buf, int buf_len, | |
86 net::CompletionCallback* callback) { | |
Wez
2011/08/02 23:13:24
nit: Indentation.
Sergey Ulanov
2011/08/03 00:02:16
Done.
| |
87 DCHECK(CalledOnValidThread()); | |
88 DCHECK(!write_callback_); | |
89 DCHECK(!write_buffer_); | |
90 | |
91 int result = PPErrorToNetError(transport_->Send( | |
92 buf->data(), buf_len, | |
93 callback_factory_.NewOptionalCallback( | |
94 &PepperTransportSocketAdaptor::OnWrite))); | |
Wez
2011/08/02 23:13:24
No need to be optional?
Sergey Ulanov
2011/08/03 00:02:16
Same as Read()
| |
95 | |
96 if (result == net::ERR_IO_PENDING) { | |
97 write_callback_ = callback; | |
98 write_buffer_ = buf; | |
99 } | |
100 | |
101 return result; | |
102 } | |
103 | |
104 bool PepperTransportSocketAdaptor::SetReceiveBufferSize(int32 size) { | |
105 DCHECK(CalledOnValidThread()); | |
106 NOTIMPLEMENTED(); | |
Wez
2011/08/02 23:13:24
Do we need to have a bug for adding buffer-size co
Sergey Ulanov
2011/08/03 00:02:16
crbug.com/91439
| |
107 return false; | |
108 } | |
109 | |
110 bool PepperTransportSocketAdaptor::SetSendBufferSize(int32 size) { | |
111 DCHECK(CalledOnValidThread()); | |
112 NOTIMPLEMENTED(); | |
113 return false; | |
114 } | |
115 | |
116 int PepperTransportSocketAdaptor::Connect(net::CompletionCallback* callback) { | |
117 connect_callback_ = callback; | |
118 | |
119 // This will return false when the GetNextAddress() returns an | |
Wez
2011/08/02 23:13:24
nit: Don't need "the".
Sergey Ulanov
2011/08/03 00:02:16
Done.
| |
120 // error. Particularly it is useful to detect when the P2P Transport | |
121 // API is not supported. | |
Wez
2011/08/02 23:13:24
nit: "Particularly it is useful ... " -> "This hel
Sergey Ulanov
2011/08/03 00:02:16
Done.
| |
122 if (!ProcessCandidates()) | |
123 return net::ERR_FAILED; | |
Wez
2011/08/02 23:13:24
Can we return a more helpful error in this case?
Sergey Ulanov
2011/08/03 00:02:16
Done.
| |
124 | |
125 int result = transport_->Connect( | |
126 callback_factory_.NewRequiredCallback( | |
127 &PepperTransportSocketAdaptor::OnConnect)); | |
128 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); | |
129 | |
130 return net::ERR_IO_PENDING; | |
131 } | |
132 | |
133 void PepperTransportSocketAdaptor::Disconnect() { | |
134 NOTIMPLEMENTED(); | |
Wez
2011/08/02 23:13:24
How does one disconnect a Pepper stream transport?
Sergey Ulanov
2011/08/03 00:02:16
Just delete it.
Wez
2011/08/03 00:34:48
Would it make sense to simply delete |transport_|
Sergey Ulanov
2011/08/03 00:43:37
Yes, we could do that, but then we would need to h
| |
135 } | |
136 | |
137 bool PepperTransportSocketAdaptor::IsConnected() const { | |
138 return connected_; | |
139 } | |
140 | |
141 bool PepperTransportSocketAdaptor::IsConnectedAndIdle() const { | |
142 NOTIMPLEMENTED(); | |
143 return false; | |
144 } | |
145 | |
146 int PepperTransportSocketAdaptor::GetPeerAddress( | |
147 net::AddressList* address) const { | |
148 NOTIMPLEMENTED(); | |
149 return net::ERR_FAILED; | |
150 } | |
151 | |
152 int PepperTransportSocketAdaptor::GetLocalAddress( | |
153 net::IPEndPoint* address) const { | |
154 NOTIMPLEMENTED(); | |
155 return net::ERR_FAILED; | |
156 } | |
157 | |
158 const net::BoundNetLog& PepperTransportSocketAdaptor::NetLog() const { | |
159 return net_log_; | |
160 } | |
161 | |
162 void PepperTransportSocketAdaptor::SetSubresourceSpeculation() { | |
163 NOTIMPLEMENTED(); | |
164 } | |
165 | |
166 void PepperTransportSocketAdaptor::SetOmniboxSpeculation() { | |
167 NOTIMPLEMENTED(); | |
168 } | |
169 | |
170 bool PepperTransportSocketAdaptor::WasEverUsed() const { | |
171 return true; | |
Wez
2011/08/02 23:13:24
nit: NOTIMPLEMENTED(), too?
Sergey Ulanov
2011/08/03 00:02:16
Done.
| |
172 } | |
173 | |
174 bool PepperTransportSocketAdaptor::UsingTCPFastOpen() const { | |
175 NOTIMPLEMENTED(); | |
176 return true; | |
177 } | |
178 | |
179 int64 PepperTransportSocketAdaptor::NumBytesRead() const { | |
180 NOTIMPLEMENTED(); | |
181 return 0; | |
182 } | |
183 | |
184 base::TimeDelta PepperTransportSocketAdaptor::GetConnectTimeMicros() const { | |
185 NOTIMPLEMENTED(); | |
186 return base::TimeDelta(); | |
187 } | |
188 | |
189 | |
190 bool PepperTransportSocketAdaptor::ProcessCandidates() { | |
191 DCHECK(CalledOnValidThread()); | |
192 DCHECK(!get_address_pending_); | |
193 | |
194 while (true) { | |
195 pp::Var address; | |
196 int result = transport_->GetNextAddress( | |
197 &address, callback_factory_.NewOptionalCallback( | |
198 &PepperTransportSocketAdaptor::OnNextAddress)); | |
Wez
2011/08/02 23:13:24
Simplify this by making it use a required callback
Sergey Ulanov
2011/08/03 00:02:16
That's not possible with GetNextAddress(). Semanti
Wez
2011/08/03 00:34:48
OK. The GetNextAddress() interface strikes me as
| |
199 if (result == PP_OK_COMPLETIONPENDING) { | |
200 get_address_pending_ = true; | |
201 break; | |
202 } | |
203 | |
204 if (result == PP_OK) { | |
205 observer_->OnChannelNewCandidate(address.AsString()); | |
206 } else { | |
207 LOG(ERROR) << "GetNextAddress() returned an error " << result; | |
208 return false; | |
209 } | |
210 } | |
211 return true; | |
212 } | |
213 | |
214 void PepperTransportSocketAdaptor::OnNextAddress(int32_t result) { | |
215 DCHECK(CalledOnValidThread()); | |
216 | |
217 get_address_pending_ = false; | |
218 ProcessCandidates(); | |
219 } | |
220 | |
221 void PepperTransportSocketAdaptor::OnConnect(int result) { | |
222 DCHECK(connect_callback_); | |
223 | |
224 if (result == PP_OK) | |
225 connected_ = true; | |
226 | |
227 net::CompletionCallback* callback = connect_callback_; | |
228 connect_callback_ = NULL; | |
229 callback->Run(PPErrorToNetError(result)); | |
230 } | |
231 | |
232 void PepperTransportSocketAdaptor::OnRead(int32_t result) { | |
233 DCHECK(CalledOnValidThread()); | |
234 DCHECK(read_callback_); | |
235 DCHECK(read_buffer_); | |
236 | |
237 net::CompletionCallback* callback = read_callback_; | |
238 read_callback_ = NULL; | |
239 read_buffer_ = NULL; | |
240 callback->Run(PPErrorToNetError(result)); | |
241 } | |
242 | |
243 void PepperTransportSocketAdaptor::OnWrite(int32_t result) { | |
244 DCHECK(CalledOnValidThread()); | |
245 DCHECK(write_callback_); | |
246 DCHECK(write_buffer_); | |
247 | |
248 net::CompletionCallback* callback = write_callback_; | |
249 write_callback_ = NULL; | |
250 write_buffer_ = NULL; | |
251 callback->Run(PPErrorToNetError(result)); | |
252 } | |
253 | |
254 } // namespace protocol | |
255 } // namespace remoting | |
OLD | NEW |