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

Unified Diff: chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc

Issue 349433002: chrome.bluetoothLowEnergy: Introduce connect and disconnect methods. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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: chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
index 9e2761ece155b53db7bb6a730aaf1cd018b60865..b419e276453cd03824ee9d0b2ac58f8d1bc2e213 100644
--- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
@@ -7,11 +7,13 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/values.h"
+#include "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_connection.h"
#include "chrome/browser/extensions/api/bluetooth_low_energy/utils.h"
#include "chrome/common/extensions/api/bluetooth/bluetooth_manifest_data.h"
#include "content/public/browser/browser_thread.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_gatt_characteristic.h"
+#include "device/bluetooth/bluetooth_gatt_connection.h"
#include "device/bluetooth/bluetooth_gatt_descriptor.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_registry.h"
@@ -22,6 +24,7 @@ using device::BluetoothAdapter;
using device::BluetoothAdapterFactory;
using device::BluetoothDevice;
using device::BluetoothGattCharacteristic;
+using device::BluetoothGattConnection;
using device::BluetoothGattDescriptor;
using device::BluetoothGattService;
@@ -120,6 +123,19 @@ void PopulateDescriptor(const BluetoothGattDescriptor* descriptor,
out->value.reset(new std::string(value.begin(), value.end()));
}
+typedef extensions::ApiResourceManager<extensions::BluetoothLowEnergyConnection>
+ ConnectionResourceManager;
+ConnectionResourceManager* GetConnectionResourceManager(
+ content::BrowserContext* context) {
+ ConnectionResourceManager* manager = ConnectionResourceManager::Get(context);
+ DCHECK(manager)
+ << "There is no Bluetooth low energy connection manager. "
+ "If this assertion is failing during a test, then it is likely that "
+ "TestExtensionSystem is failing to provide an instance of "
+ "ApiResourceManager<BluetoothLowEnergyConnection>.";
+ return manager;
+}
+
} // namespace
namespace extensions {
@@ -193,6 +209,86 @@ bool BluetoothLowEnergyEventRouter::HasAdapter() const {
return (adapter_.get() != NULL);
}
+BluetoothLowEnergyEventRouter::Status BluetoothLowEnergyEventRouter::Connect(
+ const Extension* extension,
+ const std::string& device_address,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!adapter_) {
+ VLOG(1) << "BluetoothAdapter not ready.";
+ return kStatusErrorFailed;
+ }
+
+ if (connecting_devices_.count(device_address) != 0)
+ return kStatusErrorInProgress;
+
+ const std::string extension_id = extension->id();
+ BluetoothLowEnergyConnection* conn =
+ FindConnection(extension_id, device_address);
+ if (conn) {
+ if (conn->GetConnection()->IsConnected()) {
+ VLOG(1) << "Application already connected to device: " << device_address;
+ return kStatusErrorAlreadyConnected;
+ }
+
+ // There is a connection object but it's no longer active. Simply remove it.
+ RemoveConnection(extension_id, device_address);
+ }
+
+ BluetoothDevice* device = adapter_->GetDevice(device_address);
+ if (!device) {
+ VLOG(1) << "Bluetooth device not found: " << device_address;
+ return kStatusErrorNotFound;
+ }
+
+ connecting_devices_.insert(device_address);
+ device->CreateGattConnection(
+ base::Bind(&BluetoothLowEnergyEventRouter::OnCreateGattConnection,
+ weak_ptr_factory_.GetWeakPtr(),
+ extension_id,
+ device_address,
+ callback),
+ base::Bind(&BluetoothLowEnergyEventRouter::OnConnectError,
+ weak_ptr_factory_.GetWeakPtr(),
+ device_address,
+ error_callback));
+
+ return kStatusSuccess;
+}
+
+BluetoothLowEnergyEventRouter::Status BluetoothLowEnergyEventRouter::Disconnect(
+ const Extension* extension,
+ const std::string& device_address,
+ const base::Closure& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!adapter_) {
+ VLOG(1) << "BluetoothAdapter not ready.";
+ return kStatusErrorFailed;
+ }
+
+ if (disconnecting_devices_.count(device_address) != 0)
+ return kStatusErrorInProgress;
+
+ const std::string& extension_id = extension->id();
+ BluetoothLowEnergyConnection* conn =
+ FindConnection(extension_id, device_address);
+ if (!conn || !conn->GetConnection()->IsConnected()) {
+ VLOG(1) << "Application not connected to device: " << device_address;
+ return kStatusErrorNotConnected;
+ }
+
+ disconnecting_devices_.insert(device_address);
+ conn->GetConnection()->Disconnect(
+ base::Bind(&BluetoothLowEnergyEventRouter::OnDisconnect,
+ weak_ptr_factory_.GetWeakPtr(),
+ extension_id,
+ device_address,
+ callback));
+
+ return kStatusSuccess;
+}
+
bool BluetoothLowEnergyEventRouter::GetServices(
const std::string& device_address,
ServiceList* out_services) const {
@@ -1007,10 +1103,107 @@ void BluetoothLowEnergyEventRouter::OnValueSuccess(
callback.Run();
}
+void BluetoothLowEnergyEventRouter::OnCreateGattConnection(
+ const std::string& extension_id,
+ const std::string& device_address,
+ const base::Closure& callback,
+ scoped_ptr<BluetoothGattConnection> connection) {
+ VLOG(2) << "GATT connection created.";
+ DCHECK(connection.get());
+ DCHECK(!FindConnection(extension_id, device_address));
+ DCHECK_EQ(device_address, connection->GetDeviceAddress());
+ DCHECK_NE(0U, connecting_devices_.count(device_address));
+
+ BluetoothLowEnergyConnection* conn =
+ new BluetoothLowEnergyConnection(extension_id, connection.Pass());
+ ConnectionResourceManager* manager =
+ GetConnectionResourceManager(browser_context_);
+ manager->Add(conn);
+
+ connecting_devices_.erase(device_address);
+ callback.Run();
+}
+
+void BluetoothLowEnergyEventRouter::OnDisconnect(
+ const std::string& extension_id,
+ const std::string& device_address,
+ const base::Closure& callback) {
+ VLOG(2) << "GATT connection terminated.";
+ DCHECK_NE(0U, disconnecting_devices_.count(device_address));
+ if (!RemoveConnection(extension_id, device_address)) {
+ VLOG(1) << "The connection was removed before disconnect completed, id: "
+ << extension_id << ", device: " << device_address;
+ }
+
+ disconnecting_devices_.erase(device_address);
+ callback.Run();
+}
+
void BluetoothLowEnergyEventRouter::OnError(
const ErrorCallback& error_callback) {
VLOG(2) << "Remote characteristic/descriptor value read/write failed.";
error_callback.Run(kStatusErrorFailed);
}
+void BluetoothLowEnergyEventRouter::OnConnectError(
+ const std::string& device_address,
+ const ErrorCallback& error_callback,
+ BluetoothDevice::ConnectErrorCode error_code) {
+ VLOG(2) << "Failed to create GATT connection: " << error_code;
+ DCHECK_NE(0U, connecting_devices_.count(device_address));
+
+ connecting_devices_.erase(device_address);
+ error_callback.Run(kStatusErrorFailed);
+}
+
+BluetoothLowEnergyConnection* BluetoothLowEnergyEventRouter::FindConnection(
+ const std::string& extension_id,
+ const std::string& device_address) {
+ ConnectionResourceManager* manager =
+ GetConnectionResourceManager(browser_context_);
+
+ base::hash_set<int>* connection_ids = manager->GetResourceIds(extension_id);
+ if (!connection_ids)
+ return NULL;
+
+ for (base::hash_set<int>::const_iterator iter = connection_ids->begin();
+ iter != connection_ids->end();
+ ++iter) {
+ extensions::BluetoothLowEnergyConnection* conn =
+ manager->Get(extension_id, *iter);
+ if (!conn)
+ continue;
+
+ if (conn->GetConnection()->GetDeviceAddress() == device_address)
+ return conn;
+ }
+
+ return NULL;
+}
+
+bool BluetoothLowEnergyEventRouter::RemoveConnection(
+ const std::string& extension_id,
+ const std::string& device_address) {
+ ConnectionResourceManager* manager =
+ GetConnectionResourceManager(browser_context_);
+
+ base::hash_set<int>* connection_ids = manager->GetResourceIds(extension_id);
+ if (!connection_ids)
+ return false;
+
+ for (base::hash_set<int>::const_iterator iter = connection_ids->begin();
+ iter != connection_ids->end();
+ ++iter) {
+ extensions::BluetoothLowEnergyConnection* conn =
+ manager->Get(extension_id, *iter);
+ if (!conn || conn->GetConnection()->GetDeviceAddress() != device_address)
+ continue;
+
+ manager->Remove(extension_id, *iter);
+ return true;
+ }
+
+ return false;
+}
+
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698