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

Unified Diff: components/proximity_auth/bluetooth_connection.cc

Issue 585743004: [Easy Unlock] Port the BluetoothConnection class to native code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix scoped_refptr compile on non-clang Created 6 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: components/proximity_auth/bluetooth_connection.cc
diff --git a/components/proximity_auth/bluetooth_connection.cc b/components/proximity_auth/bluetooth_connection.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fdc7103219096d24372cc73747949a532a922bd2
--- /dev/null
+++ b/components/proximity_auth/bluetooth_connection.cc
@@ -0,0 +1,201 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/proximity_auth/bluetooth_connection.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/numerics/safe_conversions.h"
+#include "components/proximity_auth/bluetooth_util.h"
+#include "components/proximity_auth/remote_device.h"
+#include "components/proximity_auth/wire_message.h"
+#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_device.h"
+#include "net/base/io_buffer.h"
+
+namespace proximity_auth {
+namespace {
+const int kReceiveBufferSizeBytes = 1024;
+}
+
+BluetoothConnection::BluetoothConnection(const RemoteDevice& remote_device,
+ const device::BluetoothUUID& uuid)
+ : Connection(remote_device), uuid_(uuid), weak_ptr_factory_(this) {
+}
+
+BluetoothConnection::~BluetoothConnection() {
+ Disconnect();
+}
+
+void BluetoothConnection::Connect() {
+ if (status() != DISCONNECTED) {
+ VLOG(1)
+ << "[BC] Ignoring attempt to connect a non-disconnected connection.";
+ return;
+ }
+
+ if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
+ VLOG(1)
+ << "[BC] Connection failed: Bluetooth is unsupported on this platform.";
+ return;
+ }
+
+ SetStatus(IN_PROGRESS);
+ device::BluetoothAdapterFactory::GetAdapter(
+ base::Bind(&BluetoothConnection::OnAdapterInitialized,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void BluetoothConnection::Disconnect() {
+ if (status() == DISCONNECTED) {
+ VLOG(1)
+ << "[BC] Ignoring attempt to disconnect a non-connected connection.";
+ return;
+ }
+
+ // Set status as disconnected now, rather than after the socket closes, so
+ // this connection is not reused.
+ SetStatus(DISCONNECTED);
+ if (socket_.get()) {
+ socket_->Disconnect(base::Bind(&base::DoNothing));
+ socket_ = NULL;
+ }
+ if (adapter_.get()) {
+ adapter_->RemoveObserver(this);
+ adapter_ = NULL;
+ }
+}
+
+void BluetoothConnection::SendMessageImpl(scoped_ptr<WireMessage> message) {
+ DCHECK_EQ(status(), CONNECTED);
+
+ // Serialize the message.
+ std::string serialized_message = message->Serialize();
+ int message_length = base::checked_cast<int>(serialized_message.size());
+ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(message_length);
+ memcpy(buffer->data(), serialized_message.c_str(), message_length);
+
+ // Send it.
+ pending_message_ = message.Pass();
+ base::WeakPtr<BluetoothConnection> weak_this = weak_ptr_factory_.GetWeakPtr();
+ socket_->Send(buffer,
+ message_length,
+ base::Bind(&BluetoothConnection::OnSend, weak_this),
+ base::Bind(&BluetoothConnection::OnSendError, weak_this));
+}
+
+void BluetoothConnection::DeviceRemoved(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) {
+ DCHECK_EQ(adapter, adapter_.get());
+ if (device->GetAddress() != remote_device().bluetooth_address)
+ return;
+
+ DCHECK_NE(status(), DISCONNECTED);
+ VLOG(1) << "[BC] Device disconnected...";
+ Disconnect();
+}
+
+void BluetoothConnection::ConnectToService(
+ device::BluetoothDevice* device,
+ const device::BluetoothUUID& uuid,
+ const device::BluetoothDevice::ConnectToServiceCallback& callback,
+ const device::BluetoothDevice::ConnectToServiceErrorCallback&
+ error_callback) {
+ bluetooth_util::ConnectToServiceInsecurely(
+ device, uuid, callback, error_callback);
+}
+
+void BluetoothConnection::StartReceive() {
+ base::WeakPtr<BluetoothConnection> weak_this = weak_ptr_factory_.GetWeakPtr();
+ socket_->Receive(kReceiveBufferSizeBytes,
+ base::Bind(&BluetoothConnection::OnReceive, weak_this),
+ base::Bind(&BluetoothConnection::OnReceiveError, weak_this));
+}
+
+void BluetoothConnection::OnAdapterInitialized(
+ scoped_refptr<device::BluetoothAdapter> adapter) {
+ const std::string address = remote_device().bluetooth_address;
+ device::BluetoothDevice* bluetooth_device = adapter->GetDevice(address);
+ if (!bluetooth_device) {
Tim Song 2014/09/22 23:30:38 Reading this code gave me the thought that it woul
Ilya Sherman 2014/09/23 05:24:22 Yeah, I think that makes sense. I'll go ahead and
+ VLOG(1) << "[BC] Device with address " << address
+ << " is not known to the system Bluetooth daemon.";
+ Disconnect();
+ return;
+ }
+
+ adapter_ = adapter;
+ adapter_->AddObserver(this);
+
+ base::WeakPtr<BluetoothConnection> weak_this = weak_ptr_factory_.GetWeakPtr();
+ ConnectToService(
+ bluetooth_device,
+ uuid_,
+ base::Bind(&BluetoothConnection::OnConnected, weak_this),
+ base::Bind(&BluetoothConnection::OnConnectionError, weak_this));
+}
+
+void BluetoothConnection::OnConnected(
+ scoped_refptr<device::BluetoothSocket> socket) {
+ if (status() != IN_PROGRESS) {
+ // This case is reachable if the client of |this| connection called
+ // |Disconnect()| while the backing Bluetooth connection was pending.
+ DCHECK_EQ(status(), DISCONNECTED);
+ VLOG(1) << "[BC] Ignoring successful backend Bluetooth connection to an "
+ << "already disconnected logical connection.";
+ return;
+ }
+
+ VLOG(1) << "[BC] Connection established with "
+ << remote_device().bluetooth_address;
+ socket_ = socket;
+ SetStatus(CONNECTED);
+ StartReceive();
+}
+
+void BluetoothConnection::OnConnectionError(const std::string& error_message) {
+ VLOG(1) << "[BC] Connection failed: " << error_message;
+ Disconnect();
+}
+
+void BluetoothConnection::OnSend(int bytes_sent) {
+ VLOG(1) << "[BC] Successfully sent " << bytes_sent << " bytes.";
+ OnDidSendMessage(*pending_message_, true);
+ pending_message_.reset();
+}
+
+void BluetoothConnection::OnSendError(const std::string& error_message) {
+ VLOG(1) << "[BC] Error when sending bytes: " << error_message;
+ OnDidSendMessage(*pending_message_, false);
+ pending_message_.reset();
+
+ Disconnect();
+}
+
+void BluetoothConnection::OnReceive(int bytes_received,
+ scoped_refptr<net::IOBuffer> buffer) {
+ VLOG(1) << "[BC] Received " << bytes_received << " bytes.";
+ OnBytesReceived(std::string(buffer->data(), bytes_received));
+
+ // Post a task to delay the read until the socket is available, as
+ // calling StartReceive at this point would error with ERR_IO_PENDING.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&BluetoothConnection::StartReceive,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void BluetoothConnection::OnReceiveError(
+ device::BluetoothSocket::ErrorReason error_reason,
+ const std::string& error_message) {
+ VLOG(1) << "[BC] Error receiving bytes: " << error_message;
+
+ // Post a task to delay the read until the socket is available, as
+ // calling StartReceive at this point would error with ERR_IO_PENDING.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&BluetoothConnection::StartReceive,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+} // namespace proximity_auth

Powered by Google App Engine
This is Rietveld 408576698