diff options
author | sacomoto <sacomoto@chromium.org> | 2015-04-27 03:04:26 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-27 10:04:27 +0000 |
commit | 8d080c8e59b18ef4dc46f3a03cc6a15f634868af (patch) | |
tree | 3ecda0888a9cf59466cc84a424b4f1ed1cc78307 | |
parent | 76a7e3446188256ca240dc31cd5287ef78de2951 (diff) | |
download | chromium_src-8d080c8e59b18ef4dc46f3a03cc6a15f634868af.zip chromium_src-8d080c8e59b18ef4dc46f3a03cc6a15f634868af.tar.gz chromium_src-8d080c8e59b18ef4dc46f3a03cc6a15f634868af.tar.bz2 |
Implementing a BLE connection finder.
This is a fixed version of https://codereview.chromium.org/1094273003/,
that was reverted due to a global const std:string.
BUG=479673
Review URL: https://codereview.chromium.org/1102093002
Cr-Commit-Position: refs/heads/master@{#327022}
6 files changed, 315 insertions, 2 deletions
diff --git a/components/proximity_auth.gypi b/components/proximity_auth.gypi index 8a5526c..c5fcc84 100644 --- a/components/proximity_auth.gypi +++ b/components/proximity_auth.gypi @@ -16,6 +16,10 @@ '../net/net.gyp:net', ], 'sources': [ + "proximity_auth/ble/bluetooth_low_energy_connection_finder.cc", + "proximity_auth/ble/bluetooth_low_energy_connection_finder.h", + "proximity_auth/ble/proximity_auth_ble_system.cc", + "proximity_auth/ble/proximity_auth_ble_system.h", "proximity_auth/bluetooth_connection.cc", "proximity_auth/bluetooth_connection.h", "proximity_auth/bluetooth_connection_finder.cc", @@ -26,8 +30,6 @@ "proximity_auth/bluetooth_util.cc", "proximity_auth/bluetooth_util.h", "proximity_auth/bluetooth_util_chromeos.cc", - "proximity_auth/ble/proximity_auth_ble_system.cc", - "proximity_auth/ble/proximity_auth_ble_system.h", "proximity_auth/client.cc", "proximity_auth/client.h", "proximity_auth/client_observer.h", diff --git a/components/proximity_auth/ble/BUILD.gn b/components/proximity_auth/ble/BUILD.gn index db2d0db..71324c5 100644 --- a/components/proximity_auth/ble/BUILD.gn +++ b/components/proximity_auth/ble/BUILD.gn @@ -4,6 +4,8 @@ source_set("ble") { sources = [ + "bluetooth_low_energy_connection_finder.cc", + "bluetooth_low_energy_connection_finder.h", "proximity_auth_ble_system.cc", "proximity_auth_ble_system.h", ] diff --git a/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc new file mode 100644 index 0000000..0fdec85 --- /dev/null +++ b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc @@ -0,0 +1,181 @@ +// Copyright 2015 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/ble/bluetooth_low_energy_connection_finder.h" + +#include <string> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/logging.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/bluetooth_discovery_session.h" +#include "device/bluetooth/bluetooth_uuid.h" + +using device::BluetoothAdapter; +using device::BluetoothDevice; +using device::BluetoothGattConnection; + +namespace proximity_auth { + +BluetoothLowEnergyConnectionFinder::BluetoothLowEnergyConnectionFinder( + const std::string& remote_service_uuid) + : remote_service_uuid_(device::BluetoothUUID(remote_service_uuid)), + connected_(false), + weak_ptr_factory_(this) { +} + +BluetoothLowEnergyConnectionFinder::~BluetoothLowEnergyConnectionFinder() { + if (discovery_session_) { + StopDiscoverySession(); + } + if (adapter_) { + adapter_->RemoveObserver(this); + adapter_ = NULL; + } +} + +void BluetoothLowEnergyConnectionFinder::Find( + const BluetoothDevice::GattConnectionCallback& connection_callback) { + if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { + VLOG(1) << "[BCF] Bluetooth is unsupported on this platform. Aborting."; + return; + } + VLOG(1) << "Finding connection"; + + connection_callback_ = connection_callback; + + device::BluetoothAdapterFactory::GetAdapter( + base::Bind(&BluetoothLowEnergyConnectionFinder::OnAdapterInitialized, + weak_ptr_factory_.GetWeakPtr())); +} + +void BluetoothLowEnergyConnectionFinder::Find( + const ConnectionCallback& connection_callback) { + NOTREACHED(); +} + +void BluetoothLowEnergyConnectionFinder::DeviceAdded(BluetoothAdapter* adapter, + BluetoothDevice* device) { + if (device) { + VLOG(1) << "New device found: " << device->GetName(); + HandleDeviceAdded(device); + } +} + +void BluetoothLowEnergyConnectionFinder::OnAdapterInitialized( + scoped_refptr<BluetoothAdapter> adapter) { + VLOG(1) << "Adapter ready"; + + adapter_ = adapter; + adapter_->AddObserver(this); + + std::vector<BluetoothDevice*> devices = adapter_->GetDevices(); + for (auto iter = devices.begin(); iter != devices.end(); iter++) { + HandleDeviceAdded((*iter)); + } + + StartDiscoverySession(); +} + +void BluetoothLowEnergyConnectionFinder::HandleDeviceAdded( + BluetoothDevice* remote_device) { + if (!connected_ && HasService(remote_device)) { + CreateConnection(remote_device); + } +} + +void BluetoothLowEnergyConnectionFinder::OnDiscoverySessionStarted( + scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { + VLOG(1) << "Discovery session started"; + discovery_session_ = discovery_session.Pass(); +} + +void BluetoothLowEnergyConnectionFinder::OnStartDiscoverySessionError() { + VLOG(1) << "Error starting discovery session"; +} + +void BluetoothLowEnergyConnectionFinder::StartDiscoverySession() { + DCHECK(adapter_); + if (discovery_session_ && discovery_session_->IsActive()) { + VLOG(1) << "Discovery session already active"; + return; + } + adapter_->StartDiscoverySession( + base::Bind(&BluetoothLowEnergyConnectionFinder::OnDiscoverySessionStarted, + weak_ptr_factory_.GetWeakPtr()), + base::Bind( + &BluetoothLowEnergyConnectionFinder::OnStartDiscoverySessionError, + weak_ptr_factory_.GetWeakPtr())); +} + +void BluetoothLowEnergyConnectionFinder::OnDiscoverySessionStopped() { + VLOG(1) << "Discovery session stopped"; + discovery_session_.reset(); +} + +void BluetoothLowEnergyConnectionFinder::OnStopDiscoverySessionError() { + VLOG(1) << "Error stopping discovery session"; +} + +void BluetoothLowEnergyConnectionFinder::StopDiscoverySession() { + VLOG(1) << "Stopping discovery sesison"; + + if (!adapter_) { + VLOG(1) << "Adapter not initialized"; + return; + } + if (!discovery_session_ || !discovery_session_->IsActive()) { + VLOG(1) << "No Active discovery session"; + } + + discovery_session_->Stop( + base::Bind(&BluetoothLowEnergyConnectionFinder::OnDiscoverySessionStopped, + weak_ptr_factory_.GetWeakPtr()), + base::Bind( + &BluetoothLowEnergyConnectionFinder::OnStopDiscoverySessionError, + weak_ptr_factory_.GetWeakPtr())); +} + +bool BluetoothLowEnergyConnectionFinder::HasService( + BluetoothDevice* remote_device) { + if (remote_device) { + std::vector<device::BluetoothUUID> uuids = remote_device->GetUUIDs(); + for (auto iter = uuids.begin(); iter != uuids.end(); iter++) { + if (remote_service_uuid_ == *iter) { + return true; + } + } + } + return false; +} + +void BluetoothLowEnergyConnectionFinder::OnCreateConnectionError( + BluetoothDevice::ConnectErrorCode error_code) { + VLOG(1) << "Error creating connection"; +} + +void BluetoothLowEnergyConnectionFinder::OnConnectionCreated( + scoped_ptr<BluetoothGattConnection> connection) { + VLOG(1) << "Connection created"; + connected_ = true; + StopDiscoverySession(); + connection_callback_.Run(connection.Pass()); +} + +void BluetoothLowEnergyConnectionFinder::CreateConnection( + device::BluetoothDevice* remote_device) { + VLOG(1) << "SmartLock service found (" + << remote_service_uuid_.canonical_value() << ")\n" + << "device = " << remote_device->GetAddress() + << ", name = " << remote_device->GetName(); + remote_device->CreateGattConnection( + base::Bind(&BluetoothLowEnergyConnectionFinder::OnConnectionCreated, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothLowEnergyConnectionFinder::OnCreateConnectionError, + weak_ptr_factory_.GetWeakPtr())); +} + +} // namespace proximity_auth diff --git a/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.h b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.h new file mode 100644 index 0000000..618a502 --- /dev/null +++ b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.h @@ -0,0 +1,106 @@ +// Copyright 2015 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. + +#ifndef COMPONENTS_PROXIMITY_AUTH_BLE_BLUETOOTH_LOW_ENERGY_CONNECTION_FINDER_H +#define COMPONENTS_PROXIMITY_AUTH_BLE_BLUETOOTH_LOW_ENERGY_CONNECTION_FINDER_H + +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "components/proximity_auth/connection_finder.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/bluetooth_discovery_session.h" +#include "device/bluetooth/bluetooth_gatt_connection.h" + +namespace proximity_auth { + +// This ConnectionFinder implementation is specialized in finding a Bluetooth +// Low Energy remote device. +class BluetoothLowEnergyConnectionFinder + : public ConnectionFinder, + public device::BluetoothAdapter::Observer { + public: + BluetoothLowEnergyConnectionFinder(const std::string& remote_service_uuid); + ~BluetoothLowEnergyConnectionFinder() override; + + // Finds a connection the remote device, only the first one is functional. + void Find(const device::BluetoothDevice::GattConnectionCallback& + connection_callback); + void Find(const ConnectionCallback& connection_callback) override; + + protected: + // device::BluetoothAdapter::Observer: + void DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) override; + + private: + // Callback to be called when the Bluetooth adapter is initialized. + void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter); + + // Checks if |remote_device| contains |remote_service_uuid| and creates a + // connection in that case. + void HandleDeviceAdded(device::BluetoothDevice* remote_device); + + // Callback called when a new discovery session is started. + void OnDiscoverySessionStarted( + scoped_ptr<device::BluetoothDiscoverySession> discovery_session); + + // Callback called when there is an error starting a new discovery session. + void OnStartDiscoverySessionError(); + + // Starts a discovery session for |adapter_|. + void StartDiscoverySession(); + + // Callback called when |discovery_session_| is stopped. + void OnDiscoverySessionStopped(); + + // Callback called when there is an error stopping |discovery_session_|. + void OnStopDiscoverySessionError(); + + // Stops the discovery session given by |discovery_session_|. + void StopDiscoverySession(); + + // Checks if a service with |service_uuid| is offered by |remote_device|. + bool HasService(device::BluetoothDevice* remote_device); + + // Callback called when there is an error creating the connection. + void OnCreateConnectionError( + device::BluetoothDevice::ConnectErrorCode error_code); + + // Callback called when the connection is created. + void OnConnectionCreated( + scoped_ptr<device::BluetoothGattConnection> connection); + + // Creates a GATT connection with |remote_device|, |connection_callback_| will + // be called once the connection is established. + void CreateConnection(device::BluetoothDevice* remote_device); + + // The uuid of the service it looks for to establish a GattConnection. + device::BluetoothUUID remote_service_uuid_; + + // The Bluetooth adapter over which the Bluetooth connection will be made. + scoped_refptr<device::BluetoothAdapter> adapter_; + + // The discovery session associated to this object. + scoped_ptr<device::BluetoothDiscoverySession> discovery_session_; + + // True if there is a connection. + bool connected_; + + // Callback called when the connection is established. + device::BluetoothDevice::GattConnectionCallback connection_callback_; + + base::WeakPtrFactory<BluetoothLowEnergyConnectionFinder> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyConnectionFinder); +}; + +} // namespace proximity_auth + +#endif // COMPONENTS_PROXIMITY_AUTH_BLE_BLUETOOTH_CONNECTION_FINDER_H diff --git a/components/proximity_auth/ble/proximity_auth_ble_system.cc b/components/proximity_auth/ble/proximity_auth_ble_system.cc index b4f20e4..ecdb90d 100644 --- a/components/proximity_auth/ble/proximity_auth_ble_system.cc +++ b/components/proximity_auth/ble/proximity_auth_ble_system.cc @@ -4,16 +4,33 @@ #include "components/proximity_auth/ble/proximity_auth_ble_system.h" +#include "base/bind.h" #include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "components/proximity_auth/connection.h" +#include "device/bluetooth/bluetooth_device.h" + +#include "components/proximity_auth/ble/bluetooth_low_energy_connection_finder.h" namespace proximity_auth { +const char kSmartLockServiceUUID[] = "b3b7e28e-a000-3e17-bd86-6e97b9e28c11"; + +void ConnectionCallback( + scoped_ptr<device::BluetoothGattConnection> connection) { + VLOG(1) << "Connection established"; +} + ProximityAuthBleSystem::ProximityAuthBleSystem() { VLOG(1) << "Starting Proximity Auth over Bluetooth Low Energy."; + connection_finder_ = scoped_ptr<BluetoothLowEnergyConnectionFinder>( + new BluetoothLowEnergyConnectionFinder(kSmartLockServiceUUID)); + connection_finder_->Find(base::Bind(&ConnectionCallback)); } ProximityAuthBleSystem::~ProximityAuthBleSystem() { VLOG(1) << "Stopping Proximity over Bluetooth Low Energy."; + connection_finder_.reset(); } } // namespace proximity_auth diff --git a/components/proximity_auth/ble/proximity_auth_ble_system.h b/components/proximity_auth/ble/proximity_auth_ble_system.h index ab59bae..29ba662 100644 --- a/components/proximity_auth/ble/proximity_auth_ble_system.h +++ b/components/proximity_auth/ble/proximity_auth_ble_system.h @@ -6,6 +6,9 @@ #define COMPONENTS_PROXIMITY_AUTH_BLE_PROXIMITY_AUTH_BLE_SYSTEM_H_ #include "base/macros.h" +#include "base/memory/scoped_ptr.h" + +#include "components/proximity_auth/ble/bluetooth_low_energy_connection_finder.h" namespace proximity_auth { @@ -19,6 +22,8 @@ class ProximityAuthBleSystem { ~ProximityAuthBleSystem(); private: + scoped_ptr<BluetoothLowEnergyConnectionFinder> connection_finder_; + DISALLOW_COPY_AND_ASSIGN(ProximityAuthBleSystem); }; |