| Index: chrome/browser/extensions/api/socket/socket_api.cc
|
| diff --git a/chrome/browser/extensions/api/socket/socket_api.cc b/chrome/browser/extensions/api/socket/socket_api.cc
|
| index 6b77b6ac174787dc0ac6ddc1507c3fd62bcb6740..284f282edc8e1f2055c96c3f8b19963ecc02fc88 100644
|
| --- a/chrome/browser/extensions/api/socket/socket_api.cc
|
| +++ b/chrome/browser/extensions/api/socket/socket_api.cc
|
| @@ -25,9 +25,18 @@ const char kTCPOption[] = "tcp";
|
| const char kUDPOption[] = "udp";
|
|
|
| const char kSocketNotFoundError[] = "Socket not found";
|
| +const char kSocketTypeInvalidError[] = "Socket type is not supported";
|
| +
|
| +void SocketExtensionFunction::Work() {
|
| +}
|
| +
|
| +bool SocketExtensionFunction::Respond() {
|
| + return error_.empty();
|
| +}
|
|
|
| SocketCreateFunction::SocketCreateFunction()
|
| - : src_id_(-1),
|
| + : socket_type_(kSocketTypeInvalid),
|
| + src_id_(-1),
|
| event_notifier_(NULL) {
|
| }
|
|
|
| @@ -36,12 +45,14 @@ SocketCreateFunction::~SocketCreateFunction() {}
|
| bool SocketCreateFunction::Prepare() {
|
| std::string socket_type_string;
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &socket_type_string));
|
| - if (socket_type_string == kTCPOption)
|
| + if (socket_type_string == kTCPOption) {
|
| socket_type_ = kSocketTypeTCP;
|
| - else if (socket_type_string == kUDPOption)
|
| + } else if (socket_type_string == kUDPOption) {
|
| socket_type_ = kSocketTypeUDP;
|
| - else
|
| + } else {
|
| + error_ = kSocketTypeInvalidError;
|
| return false;
|
| + }
|
|
|
| src_id_ = ExtractSrcId(1);
|
| event_notifier_ = CreateEventNotifier(src_id_);
|
| @@ -53,32 +64,24 @@ void SocketCreateFunction::Work() {
|
| Socket* socket = NULL;
|
| if (socket_type_ == kSocketTypeTCP) {
|
| socket = new TCPSocket(event_notifier_);
|
| - } else {
|
| + } else if (socket_type_== kSocketTypeUDP) {
|
| socket = new UDPSocket(event_notifier_);
|
| }
|
| DCHECK(socket);
|
|
|
| DictionaryValue* result = new DictionaryValue();
|
| -
|
| result->SetInteger(kSocketIdKey, controller()->AddAPIResource(socket));
|
| result_.reset(result);
|
| }
|
|
|
| -bool SocketCreateFunction::Respond() {
|
| - return true;
|
| -}
|
| -
|
| bool SocketDestroyFunction::Prepare() {
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
|
| return true;
|
| }
|
|
|
| void SocketDestroyFunction::Work() {
|
| - controller()->RemoveAPIResource(socket_id_);
|
| -}
|
| -
|
| -bool SocketDestroyFunction::Respond() {
|
| - return true;
|
| + if (!controller()->RemoveAPIResource(socket_id_))
|
| + error_ = kSocketNotFoundError;
|
| }
|
|
|
| bool SocketConnectFunction::Prepare() {
|
| @@ -88,18 +91,21 @@ bool SocketConnectFunction::Prepare() {
|
| return true;
|
| }
|
|
|
| -void SocketConnectFunction::Work() {
|
| - int result = -1;
|
| +void SocketConnectFunction::AsyncWorkStart() {
|
| Socket* socket = controller()->GetSocket(socket_id_);
|
| - if (socket)
|
| - result = socket->Connect(address_, port_);
|
| - else
|
| + if (!socket) {
|
| error_ = kSocketNotFoundError;
|
| - result_.reset(Value::CreateIntegerValue(result));
|
| + OnCompleted(-1);
|
| + return;
|
| + }
|
| +
|
| + socket->Connect(address_, port_,
|
| + base::Bind(&SocketConnectFunction::OnCompleted, this));
|
| }
|
|
|
| -bool SocketConnectFunction::Respond() {
|
| - return true;
|
| +void SocketConnectFunction::OnCompleted(int result) {
|
| + result_.reset(Value::CreateIntegerValue(result));
|
| + AsyncWorkCompleted();
|
| }
|
|
|
| bool SocketDisconnectFunction::Prepare() {
|
| @@ -116,11 +122,6 @@ void SocketDisconnectFunction::Work() {
|
| result_.reset(Value::CreateNullValue());
|
| }
|
|
|
| -bool SocketDisconnectFunction::Respond() {
|
| - return true;
|
| -}
|
| -
|
| -
|
| bool SocketBindFunction::Prepare() {
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_));
|
| @@ -139,25 +140,29 @@ void SocketBindFunction::Work() {
|
| result_.reset(Value::CreateIntegerValue(result));
|
| }
|
|
|
| -bool SocketBindFunction::Respond() {
|
| - return true;
|
| -}
|
| -
|
| bool SocketReadFunction::Prepare() {
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
|
| return true;
|
| }
|
|
|
| -void SocketReadFunction::Work() {
|
| +void SocketReadFunction::AsyncWorkStart() {
|
| + Socket* socket = controller()->GetSocket(socket_id_);
|
| +
|
| + if (!socket) {
|
| + error_ = kSocketNotFoundError;
|
| + OnCompleted(-1, NULL);
|
| + return;
|
| + }
|
| +
|
| // TODO(miket): this is an arbitrary number. Can we come up with one that
|
| // makes sense?
|
| const int buffer_len = 2048;
|
| - scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(buffer_len));
|
| - Socket* socket = controller()->GetSocket(socket_id_);
|
| - int bytes_read = -1;
|
| - if (socket)
|
| - bytes_read = socket->Read(io_buffer, buffer_len);
|
| + socket->Read(buffer_len,
|
| + base::Bind(&SocketReadFunction::OnCompleted, this));
|
| +}
|
|
|
| +void SocketReadFunction::OnCompleted(int bytes_read,
|
| + scoped_refptr<net::IOBuffer> io_buffer) {
|
| // TODO(miket): the buffer-to-array functionality appears twice, once here
|
| // and once in socket.cc. When serial etc. is converted over, it'll appear
|
| // there, too. What's a good single place for it to live? Keep in mind that
|
| @@ -174,10 +179,8 @@ void SocketReadFunction::Work() {
|
| result->SetInteger(kResultCodeKey, bytes_read);
|
| result->Set(kDataKey, data_value);
|
| result_.reset(result);
|
| -}
|
|
|
| -bool SocketReadFunction::Respond() {
|
| - return true;
|
| + AsyncWorkCompleted();
|
| }
|
|
|
| SocketWriteFunction::SocketWriteFunction()
|
| @@ -209,21 +212,25 @@ bool SocketWriteFunction::Prepare() {
|
| return true;
|
| }
|
|
|
| -void SocketWriteFunction::Work() {
|
| - int bytes_written = -1;
|
| +void SocketWriteFunction::AsyncWorkStart() {
|
| Socket* socket = controller()->GetSocket(socket_id_);
|
| - if (socket)
|
| - bytes_written = socket->Write(io_buffer_, io_buffer_->size());
|
| - else
|
| +
|
| + if (!socket) {
|
| error_ = kSocketNotFoundError;
|
| + OnCompleted(-1);
|
| + return;
|
| + }
|
| +
|
| + socket->Write(io_buffer_, io_buffer_->size(),
|
| + base::Bind(&SocketWriteFunction::OnCompleted, this));
|
| +}
|
|
|
| +void SocketWriteFunction::OnCompleted(int bytes_written) {
|
| DictionaryValue* result = new DictionaryValue();
|
| result->SetInteger(kBytesWrittenKey, bytes_written);
|
| result_.reset(result);
|
| -}
|
|
|
| -bool SocketWriteFunction::Respond() {
|
| - return true;
|
| + AsyncWorkCompleted();
|
| }
|
|
|
| SocketRecvFromFunction::~SocketRecvFromFunction() {}
|
| @@ -233,19 +240,25 @@ bool SocketRecvFromFunction::Prepare() {
|
| return true;
|
| }
|
|
|
| -void SocketRecvFromFunction::Work() {
|
| +void SocketRecvFromFunction::AsyncWorkStart() {
|
| + Socket* socket = controller()->GetSocket(socket_id_);
|
| // TODO(miket): this is an arbitrary number. Can we come up with one that
|
| // makes sense?
|
| - const int buffer_len = 2048;
|
| - scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(buffer_len));
|
| - Socket* socket = controller()->GetSocket(socket_id_);
|
| - int bytes_read = -1;
|
| - std::string ip_address_str;
|
| - int port = 0;
|
| - if (socket) {
|
| - bytes_read = socket->RecvFrom(io_buffer, buffer_len, &address_);
|
| + if (!socket) {
|
| + error_ = kSocketNotFoundError;
|
| + OnCompleted(-1, NULL, std::string(), 0);
|
| + return;
|
| }
|
|
|
| + const int buffer_len = 2048;
|
| + socket->RecvFrom(buffer_len,
|
| + base::Bind(&SocketRecvFromFunction::OnCompleted, this));
|
| +}
|
| +
|
| +void SocketRecvFromFunction::OnCompleted(int bytes_read,
|
| + scoped_refptr<net::IOBuffer> io_buffer,
|
| + const std::string& address,
|
| + int port) {
|
| // TODO(miket): the buffer-to-array functionality appears twice, once here
|
| // and once in socket.cc. When serial etc. is converted over, it'll appear
|
| // there, too. What's a good single place for it to live? Keep in mind that
|
| @@ -253,7 +266,6 @@ void SocketRecvFromFunction::Work() {
|
| DictionaryValue* result = new DictionaryValue();
|
| ListValue* data_value = new ListValue();
|
| if (bytes_read > 0) {
|
| - Socket::IPEndPointToStringAndPort(address_, &ip_address_str, &port);
|
| size_t bytes_size = static_cast<size_t>(bytes_read);
|
| const char* io_buffer_start = io_buffer->data();
|
| for (size_t i = 0; i < bytes_size; ++i) {
|
| @@ -263,13 +275,11 @@ void SocketRecvFromFunction::Work() {
|
|
|
| result->SetInteger(kResultCodeKey, bytes_read);
|
| result->Set(kDataKey, data_value);
|
| - result->SetString(kAddressKey, ip_address_str);
|
| + result->SetString(kAddressKey, address);
|
| result->SetInteger(kPortKey, port);
|
| result_.reset(result);
|
| -}
|
|
|
| -bool SocketRecvFromFunction::Respond() {
|
| - return true;
|
| + AsyncWorkCompleted();
|
| }
|
|
|
| SocketSendToFunction::SocketSendToFunction()
|
| @@ -303,23 +313,24 @@ bool SocketSendToFunction::Prepare() {
|
| return true;
|
| }
|
|
|
| -void SocketSendToFunction::Work() {
|
| - int bytes_written = -1;
|
| +void SocketSendToFunction::AsyncWorkStart() {
|
| Socket* socket = controller()->GetSocket(socket_id_);
|
| - if (socket) {
|
| - bytes_written = socket->SendTo(io_buffer_, io_buffer_->size(), address_,
|
| - port_);
|
| - } else {
|
| + if (!socket) {
|
| error_ = kSocketNotFoundError;
|
| + OnCompleted(-1);
|
| + return;
|
| }
|
|
|
| + socket->SendTo(io_buffer_, io_buffer_->size(), address_, port_,
|
| + base::Bind(&SocketSendToFunction::OnCompleted, this));
|
| +}
|
| +
|
| +void SocketSendToFunction::OnCompleted(int bytes_written) {
|
| DictionaryValue* result = new DictionaryValue();
|
| result->SetInteger(kBytesWrittenKey, bytes_written);
|
| result_.reset(result);
|
| -}
|
|
|
| -bool SocketSendToFunction::Respond() {
|
| - return true;
|
| + AsyncWorkCompleted();
|
| }
|
|
|
| } // namespace extensions
|
|
|