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

Side by Side Diff: chrome/browser/extensions/api/socket/socket_api.cc

Issue 10273016: Refactor the socket API to remove onEvent callback in socket.create() function. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Update Created 8 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/browser/extensions/api/socket/socket_api.h" 5 #include "chrome/browser/extensions/api/socket/socket_api.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "chrome/browser/extensions/api/api_resource_controller.h" 8 #include "chrome/browser/extensions/api/api_resource_controller.h"
9 #include "chrome/browser/extensions/api/socket/socket.h" 9 #include "chrome/browser/extensions/api/socket/socket.h"
10 #include "chrome/browser/extensions/api/socket/tcp_socket.h" 10 #include "chrome/browser/extensions/api/socket/tcp_socket.h"
11 #include "chrome/browser/extensions/api/socket/udp_socket.h" 11 #include "chrome/browser/extensions/api/socket/udp_socket.h"
12 #include "chrome/browser/extensions/extension_service.h" 12 #include "chrome/browser/extensions/extension_service.h"
13 #include "net/base/io_buffer.h" 13 #include "net/base/io_buffer.h"
14 #include "net/base/ip_endpoint.h" 14 #include "net/base/ip_endpoint.h"
15 15
16 namespace extensions { 16 namespace extensions {
17 17
18 const char kAddressKey[] = "address"; 18 const char kAddressKey[] = "address";
19 const char kPortKey[] = "port"; 19 const char kPortKey[] = "port";
20 const char kBytesWrittenKey[] = "bytesWritten"; 20 const char kBytesWrittenKey[] = "bytesWritten";
21 const char kDataKey[] = "data"; 21 const char kDataKey[] = "data";
22 const char kResultCodeKey[] = "resultCode"; 22 const char kResultCodeKey[] = "resultCode";
23 const char kSocketIdKey[] = "socketId"; 23 const char kSocketIdKey[] = "socketId";
24 const char kTCPOption[] = "tcp"; 24 const char kTCPOption[] = "tcp";
25 const char kUDPOption[] = "udp"; 25 const char kUDPOption[] = "udp";
26 26
27 const char kSocketNotFoundError[] = "Socket not found"; 27 const char kSocketNotFoundError[] = "Socket not found";
28 const char kSocketTypeInvalidError[] = "Socket type is not supported";
29
30 void SocketExtensionFunction::Work() {
31 }
32
33 bool SocketExtensionFunction::Respond() {
34 return error_.empty();
35 }
28 36
29 SocketCreateFunction::SocketCreateFunction() 37 SocketCreateFunction::SocketCreateFunction()
30 : src_id_(-1), 38 : socket_type_(kSocketTypeInvalid),
39 src_id_(-1),
31 event_notifier_(NULL) { 40 event_notifier_(NULL) {
32 } 41 }
33 42
34 SocketCreateFunction::~SocketCreateFunction() {} 43 SocketCreateFunction::~SocketCreateFunction() {}
35 44
36 bool SocketCreateFunction::Prepare() { 45 bool SocketCreateFunction::Prepare() {
37 std::string socket_type_string; 46 std::string socket_type_string;
38 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &socket_type_string)); 47 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &socket_type_string));
39 if (socket_type_string == kTCPOption) 48 if (socket_type_string == kTCPOption) {
40 socket_type_ = kSocketTypeTCP; 49 socket_type_ = kSocketTypeTCP;
41 else if (socket_type_string == kUDPOption) 50 } else if (socket_type_string == kUDPOption) {
42 socket_type_ = kSocketTypeUDP; 51 socket_type_ = kSocketTypeUDP;
43 else 52 } else {
53 error_ = kSocketTypeInvalidError;
44 return false; 54 return false;
55 }
45 56
46 src_id_ = ExtractSrcId(1); 57 src_id_ = ExtractSrcId(1);
47 event_notifier_ = CreateEventNotifier(src_id_); 58 event_notifier_ = CreateEventNotifier(src_id_);
48 59
49 return true; 60 return true;
50 } 61 }
51 62
52 void SocketCreateFunction::Work() { 63 void SocketCreateFunction::Work() {
53 Socket* socket = NULL; 64 Socket* socket = NULL;
54 if (socket_type_ == kSocketTypeTCP) { 65 if (socket_type_ == kSocketTypeTCP) {
55 socket = new TCPSocket(event_notifier_); 66 socket = new TCPSocket(event_notifier_);
56 } else { 67 } else if (socket_type_== kSocketTypeUDP) {
57 socket = new UDPSocket(event_notifier_); 68 socket = new UDPSocket(event_notifier_);
58 } 69 }
59 DCHECK(socket); 70 DCHECK(socket);
60 71
61 DictionaryValue* result = new DictionaryValue(); 72 DictionaryValue* result = new DictionaryValue();
62
63 result->SetInteger(kSocketIdKey, controller()->AddAPIResource(socket)); 73 result->SetInteger(kSocketIdKey, controller()->AddAPIResource(socket));
64 result_.reset(result); 74 result_.reset(result);
65 } 75 }
66 76
67 bool SocketCreateFunction::Respond() {
68 return true;
69 }
70
71 bool SocketDestroyFunction::Prepare() { 77 bool SocketDestroyFunction::Prepare() {
72 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 78 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
73 return true; 79 return true;
74 } 80 }
75 81
76 void SocketDestroyFunction::Work() { 82 void SocketDestroyFunction::Work() {
77 controller()->RemoveAPIResource(socket_id_); 83 if (!controller()->RemoveAPIResource(socket_id_))
78 } 84 error_ = kSocketNotFoundError;
79
80 bool SocketDestroyFunction::Respond() {
81 return true;
82 } 85 }
83 86
84 bool SocketConnectFunction::Prepare() { 87 bool SocketConnectFunction::Prepare() {
85 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 88 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
86 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); 89 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_));
87 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); 90 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
88 return true; 91 return true;
89 } 92 }
90 93
91 void SocketConnectFunction::Work() { 94 void SocketConnectFunction::AsyncWorkStart() {
92 int result = -1;
93 Socket* socket = controller()->GetSocket(socket_id_); 95 Socket* socket = controller()->GetSocket(socket_id_);
94 if (socket) 96 if (!socket) {
95 result = socket->Connect(address_, port_);
96 else
97 error_ = kSocketNotFoundError; 97 error_ = kSocketNotFoundError;
98 result_.reset(Value::CreateIntegerValue(result)); 98 OnCompleted(-1);
99 return;
100 }
101
102 socket->Connect(address_, port_,
103 base::Bind(&SocketConnectFunction::OnCompleted, this));
99 } 104 }
100 105
101 bool SocketConnectFunction::Respond() { 106 void SocketConnectFunction::OnCompleted(int result) {
102 return true; 107 result_.reset(Value::CreateIntegerValue(result));
108 AsyncWorkCompleted();
103 } 109 }
104 110
105 bool SocketDisconnectFunction::Prepare() { 111 bool SocketDisconnectFunction::Prepare() {
106 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 112 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
107 return true; 113 return true;
108 } 114 }
109 115
110 void SocketDisconnectFunction::Work() { 116 void SocketDisconnectFunction::Work() {
111 Socket* socket = controller()->GetSocket(socket_id_); 117 Socket* socket = controller()->GetSocket(socket_id_);
112 if (socket) 118 if (socket)
113 socket->Disconnect(); 119 socket->Disconnect();
114 else 120 else
115 error_ = kSocketNotFoundError; 121 error_ = kSocketNotFoundError;
116 result_.reset(Value::CreateNullValue()); 122 result_.reset(Value::CreateNullValue());
117 } 123 }
118 124
119 bool SocketDisconnectFunction::Respond() {
120 return true;
121 }
122
123
124 bool SocketBindFunction::Prepare() { 125 bool SocketBindFunction::Prepare() {
125 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 126 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
126 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); 127 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_));
127 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); 128 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
128 return true; 129 return true;
129 } 130 }
130 131
131 void SocketBindFunction::Work() { 132 void SocketBindFunction::Work() {
132 int result = -1; 133 int result = -1;
133 Socket* socket = controller()->GetSocket(socket_id_); 134 Socket* socket = controller()->GetSocket(socket_id_);
134 if (socket) 135 if (socket)
135 result = socket->Bind(address_, port_); 136 result = socket->Bind(address_, port_);
136 else 137 else
137 error_ = kSocketNotFoundError; 138 error_ = kSocketNotFoundError;
138 139
139 result_.reset(Value::CreateIntegerValue(result)); 140 result_.reset(Value::CreateIntegerValue(result));
140 } 141 }
141 142
142 bool SocketBindFunction::Respond() {
143 return true;
144 }
145
146 bool SocketReadFunction::Prepare() { 143 bool SocketReadFunction::Prepare() {
147 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 144 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
148 return true; 145 return true;
149 } 146 }
150 147
151 void SocketReadFunction::Work() { 148 void SocketReadFunction::AsyncWorkStart() {
149 Socket* socket = controller()->GetSocket(socket_id_);
150
151 if (!socket) {
152 error_ = kSocketNotFoundError;
153 OnCompleted(-1, NULL);
154 return;
155 }
156
152 // TODO(miket): this is an arbitrary number. Can we come up with one that 157 // TODO(miket): this is an arbitrary number. Can we come up with one that
153 // makes sense? 158 // makes sense?
154 const int buffer_len = 2048; 159 const int buffer_len = 2048;
155 scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(buffer_len)); 160 socket->Read(buffer_len,
156 Socket* socket = controller()->GetSocket(socket_id_); 161 base::Bind(&SocketReadFunction::OnCompleted, this));
157 int bytes_read = -1; 162 }
158 if (socket)
159 bytes_read = socket->Read(io_buffer, buffer_len);
160 163
164 void SocketReadFunction::OnCompleted(int bytes_read,
165 scoped_refptr<net::IOBuffer> io_buffer) {
161 // TODO(miket): the buffer-to-array functionality appears twice, once here 166 // TODO(miket): the buffer-to-array functionality appears twice, once here
162 // and once in socket.cc. When serial etc. is converted over, it'll appear 167 // and once in socket.cc. When serial etc. is converted over, it'll appear
163 // there, too. What's a good single place for it to live? Keep in mind that 168 // there, too. What's a good single place for it to live? Keep in mind that
164 // this is short-term code, to be replaced with ArrayBuffer code. 169 // this is short-term code, to be replaced with ArrayBuffer code.
165 DictionaryValue* result = new DictionaryValue(); 170 DictionaryValue* result = new DictionaryValue();
166 ListValue* data_value = new ListValue(); 171 ListValue* data_value = new ListValue();
167 if (bytes_read > 0) { 172 if (bytes_read > 0) {
168 size_t bytes_size = static_cast<size_t>(bytes_read); 173 size_t bytes_size = static_cast<size_t>(bytes_read);
169 const char* io_buffer_start = io_buffer->data(); 174 const char* io_buffer_start = io_buffer->data();
170 for (size_t i = 0; i < bytes_size; ++i) { 175 for (size_t i = 0; i < bytes_size; ++i) {
171 data_value->Set(i, Value::CreateIntegerValue(io_buffer_start[i])); 176 data_value->Set(i, Value::CreateIntegerValue(io_buffer_start[i]));
172 } 177 }
173 } 178 }
174 result->SetInteger(kResultCodeKey, bytes_read); 179 result->SetInteger(kResultCodeKey, bytes_read);
175 result->Set(kDataKey, data_value); 180 result->Set(kDataKey, data_value);
176 result_.reset(result); 181 result_.reset(result);
177 }
178 182
179 bool SocketReadFunction::Respond() { 183 AsyncWorkCompleted();
180 return true;
181 } 184 }
182 185
183 SocketWriteFunction::SocketWriteFunction() 186 SocketWriteFunction::SocketWriteFunction()
184 : socket_id_(0), 187 : socket_id_(0),
185 io_buffer_(NULL) { 188 io_buffer_(NULL) {
186 } 189 }
187 190
188 SocketWriteFunction::~SocketWriteFunction() {} 191 SocketWriteFunction::~SocketWriteFunction() {}
189 192
190 bool SocketWriteFunction::Prepare() { 193 bool SocketWriteFunction::Prepare() {
(...skipping 11 matching lines...) Expand all
202 data_list_value->GetInteger(i, &int_value); 205 data_list_value->GetInteger(i, &int_value);
203 DCHECK(int_value < 256); 206 DCHECK(int_value < 256);
204 DCHECK(int_value >= 0); 207 DCHECK(int_value >= 0);
205 uint8 truncated_int = static_cast<uint8>(int_value); 208 uint8 truncated_int = static_cast<uint8>(int_value);
206 *data_buffer++ = truncated_int; 209 *data_buffer++ = truncated_int;
207 } 210 }
208 } 211 }
209 return true; 212 return true;
210 } 213 }
211 214
212 void SocketWriteFunction::Work() { 215 void SocketWriteFunction::AsyncWorkStart() {
213 int bytes_written = -1;
214 Socket* socket = controller()->GetSocket(socket_id_); 216 Socket* socket = controller()->GetSocket(socket_id_);
215 if (socket) 217
216 bytes_written = socket->Write(io_buffer_, io_buffer_->size()); 218 if (!socket) {
217 else
218 error_ = kSocketNotFoundError; 219 error_ = kSocketNotFoundError;
220 OnCompleted(-1);
221 return;
222 }
219 223
224 socket->Write(io_buffer_, io_buffer_->size(),
225 base::Bind(&SocketWriteFunction::OnCompleted, this));
226 }
227
228 void SocketWriteFunction::OnCompleted(int bytes_written) {
220 DictionaryValue* result = new DictionaryValue(); 229 DictionaryValue* result = new DictionaryValue();
221 result->SetInteger(kBytesWrittenKey, bytes_written); 230 result->SetInteger(kBytesWrittenKey, bytes_written);
222 result_.reset(result); 231 result_.reset(result);
223 }
224 232
225 bool SocketWriteFunction::Respond() { 233 AsyncWorkCompleted();
226 return true;
227 } 234 }
228 235
229 SocketRecvFromFunction::~SocketRecvFromFunction() {} 236 SocketRecvFromFunction::~SocketRecvFromFunction() {}
230 237
231 bool SocketRecvFromFunction::Prepare() { 238 bool SocketRecvFromFunction::Prepare() {
232 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 239 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
233 return true; 240 return true;
234 } 241 }
235 242
236 void SocketRecvFromFunction::Work() { 243 void SocketRecvFromFunction::AsyncWorkStart() {
244 Socket* socket = controller()->GetSocket(socket_id_);
237 // TODO(miket): this is an arbitrary number. Can we come up with one that 245 // TODO(miket): this is an arbitrary number. Can we come up with one that
238 // makes sense? 246 // makes sense?
239 const int buffer_len = 2048; 247 if (!socket) {
240 scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(buffer_len)); 248 error_ = kSocketNotFoundError;
241 Socket* socket = controller()->GetSocket(socket_id_); 249 OnCompleted(-1, NULL, std::string(), 0);
242 int bytes_read = -1; 250 return;
243 std::string ip_address_str;
244 int port = 0;
245 if (socket) {
246 bytes_read = socket->RecvFrom(io_buffer, buffer_len, &address_);
247 } 251 }
248 252
253 const int buffer_len = 2048;
254 socket->RecvFrom(buffer_len,
255 base::Bind(&SocketRecvFromFunction::OnCompleted, this));
256 }
257
258 void SocketRecvFromFunction::OnCompleted(int bytes_read,
259 scoped_refptr<net::IOBuffer> io_buffer,
260 const std::string& address,
261 int port) {
249 // TODO(miket): the buffer-to-array functionality appears twice, once here 262 // TODO(miket): the buffer-to-array functionality appears twice, once here
250 // and once in socket.cc. When serial etc. is converted over, it'll appear 263 // and once in socket.cc. When serial etc. is converted over, it'll appear
251 // there, too. What's a good single place for it to live? Keep in mind that 264 // there, too. What's a good single place for it to live? Keep in mind that
252 // this is short-term code, to be replaced with ArrayBuffer code. 265 // this is short-term code, to be replaced with ArrayBuffer code.
253 DictionaryValue* result = new DictionaryValue(); 266 DictionaryValue* result = new DictionaryValue();
254 ListValue* data_value = new ListValue(); 267 ListValue* data_value = new ListValue();
255 if (bytes_read > 0) { 268 if (bytes_read > 0) {
256 Socket::IPEndPointToStringAndPort(address_, &ip_address_str, &port);
257 size_t bytes_size = static_cast<size_t>(bytes_read); 269 size_t bytes_size = static_cast<size_t>(bytes_read);
258 const char* io_buffer_start = io_buffer->data(); 270 const char* io_buffer_start = io_buffer->data();
259 for (size_t i = 0; i < bytes_size; ++i) { 271 for (size_t i = 0; i < bytes_size; ++i) {
260 data_value->Set(i, Value::CreateIntegerValue(io_buffer_start[i])); 272 data_value->Set(i, Value::CreateIntegerValue(io_buffer_start[i]));
261 } 273 }
262 } 274 }
263 275
264 result->SetInteger(kResultCodeKey, bytes_read); 276 result->SetInteger(kResultCodeKey, bytes_read);
265 result->Set(kDataKey, data_value); 277 result->Set(kDataKey, data_value);
266 result->SetString(kAddressKey, ip_address_str); 278 result->SetString(kAddressKey, address);
267 result->SetInteger(kPortKey, port); 279 result->SetInteger(kPortKey, port);
268 result_.reset(result); 280 result_.reset(result);
269 }
270 281
271 bool SocketRecvFromFunction::Respond() { 282 AsyncWorkCompleted();
272 return true;
273 } 283 }
274 284
275 SocketSendToFunction::SocketSendToFunction() 285 SocketSendToFunction::SocketSendToFunction()
276 : socket_id_(0), 286 : socket_id_(0),
277 io_buffer_(NULL) { 287 io_buffer_(NULL) {
278 } 288 }
279 289
280 SocketSendToFunction::~SocketSendToFunction() {} 290 SocketSendToFunction::~SocketSendToFunction() {}
281 291
282 bool SocketSendToFunction::Prepare() { 292 bool SocketSendToFunction::Prepare() {
(...skipping 13 matching lines...) Expand all
296 data_list_value->GetInteger(i, &int_value); 306 data_list_value->GetInteger(i, &int_value);
297 DCHECK(int_value < 256); 307 DCHECK(int_value < 256);
298 DCHECK(int_value >= 0); 308 DCHECK(int_value >= 0);
299 uint8 truncated_int = static_cast<uint8>(int_value); 309 uint8 truncated_int = static_cast<uint8>(int_value);
300 *data_buffer++ = truncated_int; 310 *data_buffer++ = truncated_int;
301 } 311 }
302 } 312 }
303 return true; 313 return true;
304 } 314 }
305 315
306 void SocketSendToFunction::Work() { 316 void SocketSendToFunction::AsyncWorkStart() {
307 int bytes_written = -1;
308 Socket* socket = controller()->GetSocket(socket_id_); 317 Socket* socket = controller()->GetSocket(socket_id_);
309 if (socket) { 318 if (!socket) {
310 bytes_written = socket->SendTo(io_buffer_, io_buffer_->size(), address_,
311 port_);
312 } else {
313 error_ = kSocketNotFoundError; 319 error_ = kSocketNotFoundError;
320 OnCompleted(-1);
321 return;
314 } 322 }
315 323
324 socket->SendTo(io_buffer_, io_buffer_->size(), address_, port_,
325 base::Bind(&SocketSendToFunction::OnCompleted, this));
326 }
327
328 void SocketSendToFunction::OnCompleted(int bytes_written) {
316 DictionaryValue* result = new DictionaryValue(); 329 DictionaryValue* result = new DictionaryValue();
317 result->SetInteger(kBytesWrittenKey, bytes_written); 330 result->SetInteger(kBytesWrittenKey, bytes_written);
318 result_.reset(result); 331 result_.reset(result);
319 }
320 332
321 bool SocketSendToFunction::Respond() { 333 AsyncWorkCompleted();
322 return true;
323 } 334 }
324 335
325 } // namespace extensions 336 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/socket/socket_api.h ('k') | chrome/browser/extensions/api/socket/tcp_socket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698