-bool BluetoothSocketChromeOS::Receive(net::GrowableIOBuffer *buffer) {
- base::ThreadRestrictions::AssertIOAllowed();
-
- if (socket_type_ == L2CAP) {
- int count;
- if (ioctl(fd_, FIONREAD, &count) < 0) {
- error_message_ = safe_strerror(errno);
- LOG(WARNING) << "Unable to get waiting data size: " << error_message_;
- return true;
- }
-
- // No bytes waiting can mean either nothing to read, or the other end has
- // been closed, and reading zero bytes always returns zero.
- //
- // We can't do a short read for fear of a race where data arrives between
- // calls and we trunctate it. So use poll() to check for the POLLHUP flag.
- if (count == 0) {
- struct pollfd pollfd;
-
- pollfd.fd = fd_;
- pollfd.events = 0;
- pollfd.revents = 0;
-
- // Timeout parameter set to 0 so this call will not block.
- if (HANDLE_EINTR(poll(&pollfd, 1, 0)) < 0) {
- error_message_ = safe_strerror(errno);
- LOG(WARNING) << "Unable to check whether socket is closed: "
- << error_message_;
- return false;
- }
-
- if (pollfd.revents & POLLHUP) {
- // TODO(keybuk, youngki): Agree a common way to flag disconnected.
- error_message_ = "Disconnected";
- return false;
- }
- }
-
- buffer->SetCapacity(count);
- } else {
- buffer->SetCapacity(1024);
- }
-
- ssize_t bytes_read;
- do {
- if (buffer->RemainingCapacity() == 0)
- buffer->SetCapacity(buffer->capacity() * 2);
- bytes_read =
- HANDLE_EINTR(read(fd_, buffer->data(), buffer->RemainingCapacity()));
- if (bytes_read > 0)
- buffer->set_offset(buffer->offset() + bytes_read);
- } while (socket_type_ == RFCOMM && bytes_read > 0);
-
- // Ignore an error if at least one read() call succeeded; it'll be returned
- // the next read() call.
- if (buffer->offset() > 0)
- return true;
-
- if (bytes_read < 0) {
- if (errno == ECONNRESET || errno == ENOTCONN) {
- // TODO(keybuk, youngki): Agree a common way to flag disconnected.
- error_message_ = "Disconnected";
- return false;
- } else if (errno != EAGAIN && errno != EWOULDBLOCK) {
- error_message_ = safe_strerror(errno);
- return false;
- }
- }
-
- if (bytes_read == 0 && socket_type_ == RFCOMM) {
- // TODO(keybuk, youngki): Agree a common way to flag disconnected.
- error_message_ = "Disconnected";
- return false;
- }
-
- return true;
+void BluetoothSocketChromeOS::Connect(
+ scoped_ptr<dbus::FileDescriptor> fd,
+ const base::Closure& success_callback,
+ const ErrorCompletionCallback& error_callback) {
+ DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
+
+ socket_thread()->task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &BluetoothSocketChromeOS::DoConnect,
+ this,
+ base::Passed(&fd),
+ base::Bind(&BluetoothSocketChromeOS::PostSuccess,
+ this,
+ success_callback),
+ base::Bind(&BluetoothSocketChromeOS::PostErrorCompletion,
+ this,
+ error_callback)));