device/bluetooth: Add chromeos::BluetoothRemoteGattCharacteristicChromeOS.

Added the chromeos::BluetoothRemoteGattCharacteristicChromeOS class which
implements a remote instance of device::BluetoothGattCharacteristic for the
Chrome OS platform.

BUG=360266,340529
TEST=device_unittests

Review URL: https://codereview.chromium.org/228643004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262964 0039d316-1c4b-4281-b951-d872f2087c98
parent 0e188643
...@@ -49,7 +49,10 @@ void FakeBluetoothGattCharacteristicClient::Properties::Get( ...@@ -49,7 +49,10 @@ void FakeBluetoothGattCharacteristicClient::Properties::Get(
dbus::PropertyBase* property, dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) { dbus::PropertySet::GetCallback callback) {
VLOG(1) << "Get " << property->name(); VLOG(1) << "Get " << property->name();
callback.Run(false);
// TODO(armansito): Return success or failure here based on characteristic
// read permission.
callback.Run(true);
} }
void FakeBluetoothGattCharacteristicClient::Properties::GetAll() { void FakeBluetoothGattCharacteristicClient::Properties::GetAll() {
...@@ -116,8 +119,8 @@ FakeBluetoothGattCharacteristicClient::GetProperties( ...@@ -116,8 +119,8 @@ FakeBluetoothGattCharacteristicClient::GetProperties(
return heart_rate_measurement_properties_.get(); return heart_rate_measurement_properties_.get();
} }
if (object_path.value() == body_sensor_location_path_) { if (object_path.value() == body_sensor_location_path_) {
DCHECK(heart_rate_measurement_properties_.get()); DCHECK(body_sensor_location_properties_.get());
return heart_rate_measurement_properties_.get(); return body_sensor_location_properties_.get();
} }
if (object_path.value() == heart_rate_control_point_path_) { if (object_path.value() == heart_rate_control_point_path_) {
DCHECK(heart_rate_control_point_properties_.get()); DCHECK(heart_rate_control_point_properties_.get());
...@@ -226,6 +229,21 @@ void FakeBluetoothGattCharacteristicClient::HideHeartRateCharacteristics() { ...@@ -226,6 +229,21 @@ void FakeBluetoothGattCharacteristicClient::HideHeartRateCharacteristics() {
heart_rate_visible_ = false; heart_rate_visible_ = false;
} }
dbus::ObjectPath
FakeBluetoothGattCharacteristicClient::GetHeartRateMeasurementPath() const {
return dbus::ObjectPath(heart_rate_measurement_path_);
}
dbus::ObjectPath
FakeBluetoothGattCharacteristicClient::GetBodySensorLocationPath() const {
return dbus::ObjectPath(body_sensor_location_path_);
}
dbus::ObjectPath
FakeBluetoothGattCharacteristicClient::GetHeartRateControlPointPath() const {
return dbus::ObjectPath(heart_rate_control_point_path_);
}
void FakeBluetoothGattCharacteristicClient::OnPropertyChanged( void FakeBluetoothGattCharacteristicClient::OnPropertyChanged(
const dbus::ObjectPath& object_path, const dbus::ObjectPath& object_path,
const std::string& property_name) { const std::string& property_name) {
......
...@@ -56,6 +56,16 @@ class CHROMEOS_EXPORT FakeBluetoothGattCharacteristicClient ...@@ -56,6 +56,16 @@ class CHROMEOS_EXPORT FakeBluetoothGattCharacteristicClient
void ExposeHeartRateCharacteristics(const dbus::ObjectPath& service_path); void ExposeHeartRateCharacteristics(const dbus::ObjectPath& service_path);
void HideHeartRateCharacteristics(); void HideHeartRateCharacteristics();
// Returns whether or not the heart rate characteristics are visible and
// performs the appropriate assertions.
bool IsHeartRateVisible() const;
// Returns the current object paths of exposed characteristics. If the
// characteristic is not visible, returns an invalid empty path.
dbus::ObjectPath GetHeartRateMeasurementPath() const;
dbus::ObjectPath GetBodySensorLocationPath() const;
dbus::ObjectPath GetHeartRateControlPointPath() const;
// Object path components and UUIDs of GATT characteristics. // Object path components and UUIDs of GATT characteristics.
// Heart Rate Service: // Heart Rate Service:
static const char kHeartRateMeasurementPathComponent[]; static const char kHeartRateMeasurementPathComponent[];
...@@ -83,10 +93,6 @@ class CHROMEOS_EXPORT FakeBluetoothGattCharacteristicClient ...@@ -83,10 +93,6 @@ class CHROMEOS_EXPORT FakeBluetoothGattCharacteristicClient
// is a random value within a reasonable range. // is a random value within a reasonable range.
std::vector<uint8> GetHeartRateMeasurementValue(); std::vector<uint8> GetHeartRateMeasurementValue();
// Returns whether or not the heart rate characteristics are visible and
// performs the appropriate assertions.
bool IsHeartRateVisible() const;
// If true, characteristics of the Heart Rate Service are visible. Use // If true, characteristics of the Heart Rate Service are visible. Use
// IsHeartRateVisible() to check the value. // IsHeartRateVisible() to check the value.
bool heart_rate_visible_; bool heart_rate_visible_;
......
...@@ -5,12 +5,20 @@ ...@@ -5,12 +5,20 @@
#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h" #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h" #include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
#include "third_party/cros_system_api/dbus/service_constants.h" #include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos { namespace chromeos {
namespace {
const int kExposeCharacteristicsDelayIntervalMs = 100;
} // namespace
// static // static
const char FakeBluetoothGattServiceClient::kHeartRateServicePathComponent[] = const char FakeBluetoothGattServiceClient::kHeartRateServicePathComponent[] =
"service0000"; "service0000";
...@@ -46,7 +54,8 @@ void FakeBluetoothGattServiceClient::Properties::Set( ...@@ -46,7 +54,8 @@ void FakeBluetoothGattServiceClient::Properties::Set(
callback.Run(false); callback.Run(false);
} }
FakeBluetoothGattServiceClient::FakeBluetoothGattServiceClient() { FakeBluetoothGattServiceClient::FakeBluetoothGattServiceClient()
: weak_ptr_factory_(this) {
} }
FakeBluetoothGattServiceClient::~FakeBluetoothGattServiceClient() { FakeBluetoothGattServiceClient::~FakeBluetoothGattServiceClient() {
...@@ -82,7 +91,7 @@ FakeBluetoothGattServiceClient::GetProperties( ...@@ -82,7 +91,7 @@ FakeBluetoothGattServiceClient::GetProperties(
void FakeBluetoothGattServiceClient::ExposeHeartRateService( void FakeBluetoothGattServiceClient::ExposeHeartRateService(
const dbus::ObjectPath& device_path) { const dbus::ObjectPath& device_path) {
if (heart_rate_service_properties_.get()) { if (IsHeartRateVisible()) {
DCHECK(!heart_rate_service_path_.empty()); DCHECK(!heart_rate_service_path_.empty());
VLOG(1) << "Fake Heart Rate Service already exposed."; VLOG(1) << "Fake Heart Rate Service already exposed.";
return; return;
...@@ -100,15 +109,17 @@ void FakeBluetoothGattServiceClient::ExposeHeartRateService( ...@@ -100,15 +109,17 @@ void FakeBluetoothGattServiceClient::ExposeHeartRateService(
NotifyServiceAdded(dbus::ObjectPath(heart_rate_service_path_)); NotifyServiceAdded(dbus::ObjectPath(heart_rate_service_path_));
FakeBluetoothGattCharacteristicClient* char_client = base::MessageLoop::current()->PostDelayedTask(
static_cast<FakeBluetoothGattCharacteristicClient*>( FROM_HERE,
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()); base::Bind(
char_client->ExposeHeartRateCharacteristics( &FakeBluetoothGattServiceClient::ExposeHeartRateCharacteristics,
dbus::ObjectPath(heart_rate_service_path_)); weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(
kExposeCharacteristicsDelayIntervalMs));
} }
void FakeBluetoothGattServiceClient::HideHeartRateService() { void FakeBluetoothGattServiceClient::HideHeartRateService() {
if (!heart_rate_service_properties_.get()) { if (!IsHeartRateVisible()) {
DCHECK(heart_rate_service_path_.empty()); DCHECK(heart_rate_service_path_.empty());
VLOG(1) << "Fake Heart Rate Service already hidden."; VLOG(1) << "Fake Heart Rate Service already hidden.";
return; return;
...@@ -127,6 +138,15 @@ void FakeBluetoothGattServiceClient::HideHeartRateService() { ...@@ -127,6 +138,15 @@ void FakeBluetoothGattServiceClient::HideHeartRateService() {
heart_rate_service_path_.clear(); heart_rate_service_path_.clear();
} }
bool FakeBluetoothGattServiceClient::IsHeartRateVisible() const {
return !!heart_rate_service_properties_.get();
}
dbus::ObjectPath
FakeBluetoothGattServiceClient::GetHeartRateServicePath() const {
return dbus::ObjectPath(heart_rate_service_path_);
}
void FakeBluetoothGattServiceClient::OnPropertyChanged( void FakeBluetoothGattServiceClient::OnPropertyChanged(
const dbus::ObjectPath& object_path, const dbus::ObjectPath& object_path,
const std::string& property_name) { const std::string& property_name) {
...@@ -152,4 +172,16 @@ void FakeBluetoothGattServiceClient::NotifyServiceRemoved( ...@@ -152,4 +172,16 @@ void FakeBluetoothGattServiceClient::NotifyServiceRemoved(
GattServiceRemoved(object_path)); GattServiceRemoved(object_path));
} }
void FakeBluetoothGattServiceClient::ExposeHeartRateCharacteristics() {
if (!IsHeartRateVisible()) {
VLOG(2) << "Heart Rate service not visible. Not exposing characteristics.";
return;
}
FakeBluetoothGattCharacteristicClient* char_client =
static_cast<FakeBluetoothGattCharacteristicClient*>(
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient());
char_client->ExposeHeartRateCharacteristics(
dbus::ObjectPath(heart_rate_service_path_));
}
} // namespace chromeos } // namespace chromeos
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "chromeos/chromeos_export.h" #include "chromeos/chromeos_export.h"
#include "chromeos/dbus/bluetooth_gatt_service_client.h" #include "chromeos/dbus/bluetooth_gatt_service_client.h"
...@@ -54,6 +55,13 @@ class CHROMEOS_EXPORT FakeBluetoothGattServiceClient ...@@ -54,6 +55,13 @@ class CHROMEOS_EXPORT FakeBluetoothGattServiceClient
void ExposeHeartRateService(const dbus::ObjectPath& device_path); void ExposeHeartRateService(const dbus::ObjectPath& device_path);
void HideHeartRateService(); void HideHeartRateService();
// Returns whether or not the Heart Rate Service is visible.
bool IsHeartRateVisible() const;
// Returns the current object path of the visible Heart Rate service. If the
// service is not visible, returns an invalid empty path.
dbus::ObjectPath GetHeartRateServicePath() const;
// Final object path components and the corresponding UUIDs of the GATT // Final object path components and the corresponding UUIDs of the GATT
// services that we emulate. Service paths are hierarchical to Bluetooth // services that we emulate. Service paths are hierarchical to Bluetooth
// device paths, so if the path component is "service0000", and the device // device paths, so if the path component is "service0000", and the device
...@@ -71,6 +79,12 @@ class CHROMEOS_EXPORT FakeBluetoothGattServiceClient ...@@ -71,6 +79,12 @@ class CHROMEOS_EXPORT FakeBluetoothGattServiceClient
void NotifyServiceAdded(const dbus::ObjectPath& object_path); void NotifyServiceAdded(const dbus::ObjectPath& object_path);
void NotifyServiceRemoved(const dbus::ObjectPath& object_path); void NotifyServiceRemoved(const dbus::ObjectPath& object_path);
// Tells FakeBluetoothGattCharacteristicClient to expose GATT characteristics.
// This is scheduled from ExposeHeartRateService to simulate asynchronous
// retrieval of characteristics. If the Heart Rate Service is hidden at the
// time this method is called, then it does nothing.
void ExposeHeartRateCharacteristics();
// Static properties we return. As long as a service is exposed, this will be // Static properties we return. As long as a service is exposed, this will be
// non-null. Otherwise it will be null. // non-null. Otherwise it will be null.
scoped_ptr<Properties> heart_rate_service_properties_; scoped_ptr<Properties> heart_rate_service_properties_;
...@@ -79,6 +93,12 @@ class CHROMEOS_EXPORT FakeBluetoothGattServiceClient ...@@ -79,6 +93,12 @@ class CHROMEOS_EXPORT FakeBluetoothGattServiceClient
// List of observers interested in event notifications from us. // List of observers interested in event notifications from us.
ObserverList<Observer> observers_; ObserverList<Observer> observers_;
// Weak pointer factory for generating 'this' pointers that might live longer
// than we do.
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<FakeBluetoothGattServiceClient> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattServiceClient); DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattServiceClient);
}; };
......
...@@ -60,6 +60,8 @@ ...@@ -60,6 +60,8 @@
'bluetooth_profile_mac.mm', 'bluetooth_profile_mac.mm',
'bluetooth_profile_win.cc', 'bluetooth_profile_win.cc',
'bluetooth_profile_win.h', 'bluetooth_profile_win.h',
'bluetooth_remote_gatt_characteristic_chromeos.cc',
'bluetooth_remote_gatt_characteristic_chromeos.h',
'bluetooth_remote_gatt_service_chromeos.cc', 'bluetooth_remote_gatt_service_chromeos.cc',
'bluetooth_remote_gatt_service_chromeos.h', 'bluetooth_remote_gatt_service_chromeos.h',
'bluetooth_service_record.cc', 'bluetooth_service_record.cc',
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_GATT_CHARACTERISTIC_H_ #ifndef DEVICE_BLUETOOTH_BLUETOOTH_GATT_CHARACTERISTIC_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_GATT_CHARACTERISTIC_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_GATT_CHARACTERISTIC_H_
#include <string>
#include <vector> #include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
...@@ -37,6 +38,8 @@ class BluetoothGattCharacteristic { ...@@ -37,6 +38,8 @@ class BluetoothGattCharacteristic {
// indicates that there is a characteristic descriptor (namely the // indicates that there is a characteristic descriptor (namely the
// "Characteristic Extended Properties Descriptor" with UUID 0x2900) that // "Characteristic Extended Properties Descriptor" with UUID 0x2900) that
// contains additional properties pertaining to the characteristic. // contains additional properties pertaining to the characteristic.
// The properties "ReliableWrite| and |WriteAuxiliaries| are retrieved from
// that characteristic.
enum Property { enum Property {
kPropertyNone = 0, kPropertyNone = 0,
kPropertyBroadcast = 1 << 0, kPropertyBroadcast = 1 << 0,
...@@ -46,7 +49,9 @@ class BluetoothGattCharacteristic { ...@@ -46,7 +49,9 @@ class BluetoothGattCharacteristic {
kPropertyNotify = 1 << 4, kPropertyNotify = 1 << 4,
kPropertyIndicate = 1 << 5, kPropertyIndicate = 1 << 5,
kPropertyAuthenticatedSignedWrites = 1 << 6, kPropertyAuthenticatedSignedWrites = 1 << 6,
kPropertyExtendedProperties = 1 << 7 kPropertyExtendedProperties = 1 << 7,
kPropertyReliableWrite = 1 << 8,
kPropertyWriteableAuxiliaries = 1 << 9
}; };
typedef uint32 Properties; typedef uint32 Properties;
...@@ -71,7 +76,7 @@ class BluetoothGattCharacteristic { ...@@ -71,7 +76,7 @@ class BluetoothGattCharacteristic {
typedef uint32 Permissions; typedef uint32 Permissions;
// The ErrorCallback is used by methods to asynchronously report errors. // The ErrorCallback is used by methods to asynchronously report errors.
typedef base::Callback<void(const std::string&)> ErrorCallback; typedef base::Closure ErrorCallback;
// The ValueCallback is used to return the value of a remote characteristic // The ValueCallback is used to return the value of a remote characteristic
// upon a read request. // upon a read request.
...@@ -100,6 +105,13 @@ class BluetoothGattCharacteristic { ...@@ -100,6 +105,13 @@ class BluetoothGattCharacteristic {
Properties properties, Properties properties,
Permissions permissions); Permissions permissions);
// Identifier used to uniquely identify a GATT characteristic object. This is
// different from the characteristic UUID: while multiple characteristics with
// the same UUID can exist on a Bluetooth device, the identifier returned from
// this method is unique among all characteristics of a device. The contents
// of the identifier are platform specific.
virtual std::string GetIdentifier() const = 0;
// The Bluetooth-specific UUID of the characteristic. // The Bluetooth-specific UUID of the characteristic.
virtual BluetoothUUID GetUUID() const = 0; virtual BluetoothUUID GetUUID() const = 0;
...@@ -113,11 +125,17 @@ class BluetoothGattCharacteristic { ...@@ -113,11 +125,17 @@ class BluetoothGattCharacteristic {
virtual const std::vector<uint8>& GetValue() const = 0; virtual const std::vector<uint8>& GetValue() const = 0;
// Returns a pointer to the GATT service this characteristic belongs to. // Returns a pointer to the GATT service this characteristic belongs to.
virtual const BluetoothGattService* GetService() const = 0; virtual BluetoothGattService* GetService() const = 0;
// Returns the bitmask of characteristic properties.
virtual Properties GetProperties() const = 0;
// Returns the bitmask of characteristic attribute permissions.
virtual Permissions GetPermissions() const = 0;
// Returns the list of GATT characteristic descriptors that provide more // Returns the list of GATT characteristic descriptors that provide more
// information about this characteristic. // information about this characteristic.
virtual const std::vector<BluetoothGattDescriptor*> virtual std::vector<BluetoothGattDescriptor*>
GetDescriptors() const = 0; GetDescriptors() const = 0;
// Adds a characteristic descriptor to the locally hosted characteristic // Adds a characteristic descriptor to the locally hosted characteristic
...@@ -147,12 +165,11 @@ class BluetoothGattCharacteristic { ...@@ -147,12 +165,11 @@ class BluetoothGattCharacteristic {
const ErrorCallback& error_callback) = 0; const ErrorCallback& error_callback) = 0;
// Sends a write request to a remote characteristic, to modify the // Sends a write request to a remote characteristic, to modify the
// characteristic's value starting at offset |offset| with the new value // characteristic's value with the new value |new_value|. |callback| is
// |new_value|. |callback| is called to signal success and |error_callback| // called to signal success and |error_callback| for failures. This method
// for failures. This method only applies to remote characteristics and will // only applies to remote characteristics and will fail for those that are
// fail for those that are locally hosted. // locally hosted.
virtual void WriteRemoteCharacteristic( virtual void WriteRemoteCharacteristic(
int offset,
const std::vector<uint8>& new_value, const std::vector<uint8>& new_value,
const base::Closure& callback, const base::Closure& callback,
const ErrorCallback& error_callback) = 0; const ErrorCallback& error_callback) = 0;
......
...@@ -146,7 +146,7 @@ class BluetoothGattDescriptor { ...@@ -146,7 +146,7 @@ class BluetoothGattDescriptor {
// Returns a pointer to the GATT characteristic that this characteristic // Returns a pointer to the GATT characteristic that this characteristic
// descriptor belongs to. // descriptor belongs to.
virtual const BluetoothGattCharacteristic* GetCharacteristic() const = 0; virtual BluetoothGattCharacteristic* GetCharacteristic() const = 0;
// Sends a read request to a remote characteristic descriptor to read its // Sends a read request to a remote characteristic descriptor to read its
// value. |callback| is called to return the read value on success and // value. |callback| is called to return the read value on success and
......
...@@ -132,14 +132,50 @@ class BluetoothGattService { ...@@ -132,14 +132,50 @@ class BluetoothGattService {
public: public:
// Called when properties of the remote GATT service |service| have changed. // Called when properties of the remote GATT service |service| have changed.
// This will get called for properties such as UUID, as well as for changes // This will get called for properties such as UUID, as well as for changes
// to the list of known characteristics. Observers should read all GATT // to the list of known characteristics and included services. Observers
// characteristic and descriptors objects and do any necessary set up // should read all GATT characteristic and descriptors objects and do any
// required for a changed service. // necessary set up required for a changed service. This method may be
// called several times, especially when the service is discovered for the
// first time. It will be called for each characteristic that is discovered
// or removed. Hence this method should be used to check whether or not all
// characteristics of a service have been discovered that correspond to the
// profile implemented by the Observer.
virtual void GattServiceChanged(BluetoothGattService* service) {} virtual void GattServiceChanged(BluetoothGattService* service) {}
// Called when the value of a characteristic has been retrieved or updated // Called when the remote GATT characteristic |characteristic| belonging to
// via a notification or inidication. // GATT service |service| has been discovered. Use this to issue any initial
virtual void CharacteristicValueChanged( // read/write requests to the characteristic but don't cache the pointer as
// it may become invalid. Instead, use the specially assigned identifier
// to obtain a characteristic and cache that identifier as necessary, as it
// can be used to retrieve the characteristic from its GATT service. The
// number of characteristics with the same UUID belonging to a service
// depends on the particular profile the remote device implements, hence the
// client of a GATT based profile will usually operate on the whole set of
// characteristics and not just one.
//
// This method will always be followed by a call to GattServiceChanged,
// which can be used by observers to get all the characteristics of a
// service and perform the necessary updates. GattCharacteristicAdded exists
// mostly for convenience.
virtual void GattCharacteristicAdded(
BluetoothGattService* service,
BluetoothGattCharacteristic* characteristic) {}
// Called when a GATT characteristic |characteristic| belonging to GATT
// service |service| has been removed. This method is for convenience
// and will be followed by a call to GattServiceChanged (except when called
// after the service gets removed) which should be used for bootstrapping a
// GATT based profile. See the documentation of GattCharacteristicAdded and
// GattServiceChanged for more information. Try to obtain the service from
// its device to see whether or not the service has been removed.
virtual void GattCharacteristicRemoved(
BluetoothGattService* service,
BluetoothGattCharacteristic* characteristic) {}
// Called when the value of a characteristic has changed. This might be a
// result of a read/write request to, or a notification/indication from, a
// remote GATT characteristic.
virtual void GattCharacteristicValueChanged(
BluetoothGattService* service, BluetoothGattService* service,
BluetoothGattCharacteristic* characteristic, BluetoothGattCharacteristic* characteristic,
const std::vector<uint8>& value) {} const std::vector<uint8>& value) {}
...@@ -168,11 +204,11 @@ class BluetoothGattService { ...@@ -168,11 +204,11 @@ class BluetoothGattService {
bool is_primary, bool is_primary,
Delegate* delegate); Delegate* delegate);
// Identifier used to uniquely identify a GATT service object. This different // Identifier used to uniquely identify a GATT service object. This is
// from the service UUID: while multiple services with the same UUID can exist // different from the service UUID: while multiple services with the same UUID
// on a Bluetooth device, the identifier returned from this method is unique // can exist on a Bluetooth device, the identifier returned from this method
// among all services of a device. The contents of the identifier are platform // is unique among all services of a device. The contents of the identifier
// specific. // are platform specific.
virtual std::string GetIdentifier() const = 0; virtual std::string GetIdentifier() const = 0;
// The Bluetooth-specific UUID of the service. // The Bluetooth-specific UUID of the service.
...@@ -190,13 +226,18 @@ class BluetoothGattService { ...@@ -190,13 +226,18 @@ class BluetoothGattService {
virtual bool IsPrimary() const = 0; virtual bool IsPrimary() const = 0;
// List of characteristics that belong to this service. // List of characteristics that belong to this service.
virtual const std::vector<BluetoothGattCharacteristic*>& virtual std::vector<BluetoothGattCharacteristic*>
GetCharacteristics() const = 0; GetCharacteristics() const = 0;
// List of GATT services that are included by this service. // List of GATT services that are included by this service.
virtual const std::vector<BluetoothGattService*>& virtual std::vector<BluetoothGattService*>
GetIncludedServices() const = 0; GetIncludedServices() const = 0;
// Returns the GATT characteristic with identifier |identifier| if it belongs
// to this GATT service.
virtual BluetoothGattCharacteristic* GetCharacteristic(
const std::string& identifier) = 0;
// Adds characteristics and included services to the local attribute hierarchy // Adds characteristics and included services to the local attribute hierarchy
// represented by this service. These methods only make sense for local // represented by this service. These methods only make sense for local
// services and won't have an effect if this instance represents a remote // services and won't have an effect if this instance represents a remote
......
// 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 "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
namespace chromeos {
namespace {
// Stream operator for logging vector<uint8>.
std::ostream& operator<<(std::ostream& out, const std::vector<uint8> bytes) {
out << "[";
for (std::vector<uint8>::const_iterator iter = bytes.begin();
iter != bytes.end(); ++iter) {
out << base::StringPrintf("%02X", *iter);
}
return out << "]";
}
} // namespace
BluetoothRemoteGattCharacteristicChromeOS::
BluetoothRemoteGattCharacteristicChromeOS(
BluetoothRemoteGattServiceChromeOS* service,
const dbus::ObjectPath& object_path)
: object_path_(object_path),
service_(service),
weak_ptr_factory_(this) {
VLOG(1) << "Creating remote GATT characteristic with identifier: "
<< GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
}
BluetoothRemoteGattCharacteristicChromeOS::
~BluetoothRemoteGattCharacteristicChromeOS() {
}
std::string BluetoothRemoteGattCharacteristicChromeOS::GetIdentifier() const {
return object_path_.value();
}
device::BluetoothUUID
BluetoothRemoteGattCharacteristicChromeOS::GetUUID() const {
BluetoothGattCharacteristicClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
GetProperties(object_path_);
DCHECK(properties);
return device::BluetoothUUID(properties->uuid.value());
}
bool BluetoothRemoteGattCharacteristicChromeOS::IsLocal() const {
return false;
}
const std::vector<uint8>&
BluetoothRemoteGattCharacteristicChromeOS::GetValue() const {
BluetoothGattCharacteristicClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
GetProperties(object_path_);
DCHECK(properties);
return properties->value.value();
}
device::BluetoothGattService*
BluetoothRemoteGattCharacteristicChromeOS::GetService() const {
return service_;
}
device::BluetoothGattCharacteristic::Properties
BluetoothRemoteGattCharacteristicChromeOS::GetProperties() const {
// TODO(armansito): Once BlueZ implements properties properly, return those
// values here.
return kPropertyNone;
}
device::BluetoothGattCharacteristic::Permissions
BluetoothRemoteGattCharacteristicChromeOS::GetPermissions() const {
// TODO(armansito): Once BlueZ defines the permissions, return the correct
// values here.
return kPermissionNone;
}
std::vector<device::BluetoothGattDescriptor*>
BluetoothRemoteGattCharacteristicChromeOS::GetDescriptors() const {
// TODO(armansito): Return the actual descriptors here.
return std::vector<device::BluetoothGattDescriptor*>();
}
bool BluetoothRemoteGattCharacteristicChromeOS::AddDescriptor(
device::BluetoothGattDescriptor* descriptor) {
VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic.";
return false;
}
bool BluetoothRemoteGattCharacteristicChromeOS::UpdateValue(
const std::vector<uint8>& value) {
VLOG(1) << "Cannot update the value of a remote GATT characteristic.";
return false;
}
void BluetoothRemoteGattCharacteristicChromeOS::ReadRemoteCharacteristic(
const ValueCallback& callback,
const ErrorCallback& error_callback) {
VLOG(1) << "Sending GATT characteristic read request to characteristic: "
<< GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
<< ".";
BluetoothGattCharacteristicClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
GetProperties(object_path_);
DCHECK(properties);
properties->value.Get(
base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnGetValue,
weak_ptr_factory_.GetWeakPtr(),
callback, error_callback));
}
void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic(
const std::vector<uint8>& new_value,
const base::Closure& callback,
const ErrorCallback& error_callback) {
VLOG(1) << "Sending GATT characteristic write request to characteristic: "
<< GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
<< ", with value: " << new_value << ".";
// Permission and bonding are handled by BlueZ so no need check it here.
if (new_value.empty()) {
VLOG(1) << "Nothing to write.";
error_callback.Run();
return;
}
BluetoothGattCharacteristicClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
GetProperties(object_path_);
DCHECK(properties);
properties->value.Set(
new_value,
base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnSetValue,
weak_ptr_factory_.GetWeakPtr(),
callback, error_callback));
}
void BluetoothRemoteGattCharacteristicChromeOS::OnGetValue(
const ValueCallback& callback,
const ErrorCallback& error_callback,
bool success) {
if (!success) {
VLOG(1) << "Failed to read the value from the remote characteristic.";
error_callback.Run();
return;
}
VLOG(1) << "Read value of remote characteristic.";
BluetoothGattCharacteristicClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
GetProperties(object_path_);
DCHECK(properties);
callback.Run(properties->value.value());
}
void BluetoothRemoteGattCharacteristicChromeOS::OnSetValue(
const base::Closure& callback,
const ErrorCallback& error_callback,
bool success) {
if (!success) {
VLOG(1) << "Failed to write the value of remote characteristic.";
error_callback.Run();
return;
}
VLOG(1) << "Wrote value of remote characteristic.";
callback.Run();
}
} // namespace chromeos
// 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.
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
#include <string>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_gatt_characteristic.h"
#include "device/bluetooth/bluetooth_uuid.h"
namespace device {
class BluetoothGattDescriptor;
class BluetoothGattService;
} // namespace device
namespace chromeos {
class BluetoothRemoteGattServiceChromeOS;
// The BluetoothRemoteGattCharacteristicChromeOS class implements
// BluetoothGattCharacteristic for remote GATT characteristics on the Chrome OS
// platform.
class BluetoothRemoteGattCharacteristicChromeOS
: public device::BluetoothGattCharacteristic {
public:
// device::BluetoothGattCharacteristic overrides.
virtual std::string GetIdentifier() const OVERRIDE;
virtual device::BluetoothUUID GetUUID() const OVERRIDE;
virtual bool IsLocal() const OVERRIDE;
virtual const std::vector<uint8>& GetValue() const OVERRIDE;
virtual device::BluetoothGattService* GetService() const OVERRIDE;
virtual Properties GetProperties() const OVERRIDE;
virtual Permissions GetPermissions() const OVERRIDE;
virtual std::vector<device::BluetoothGattDescriptor*>
GetDescriptors() const OVERRIDE;
virtual bool AddDescriptor(
device::BluetoothGattDescriptor* descriptor) OVERRIDE;
virtual bool UpdateValue(const std::vector<uint8>& value) OVERRIDE;
virtual void ReadRemoteCharacteristic(
const ValueCallback& callback,
const ErrorCallback& error_callback) OVERRIDE;
virtual void WriteRemoteCharacteristic(
const std::vector<uint8>& new_value,
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE;
// Object path of the underlying D-Bus characteristic.
const dbus::ObjectPath& object_path() const { return object_path_; }
private:
friend class BluetoothRemoteGattServiceChromeOS;
BluetoothRemoteGattCharacteristicChromeOS(
BluetoothRemoteGattServiceChromeOS* service,
const dbus::ObjectPath& object_path);
virtual ~BluetoothRemoteGattCharacteristicChromeOS();
// Called by dbus:: on completion of the request to get the characteristic
// value.
void OnGetValue(const ValueCallback& callback,
const ErrorCallback& error_callback,
bool success);
// Called by dbus:: on completion of the request to set the characteristic
// value.
void OnSetValue(const base::Closure& callback,
const ErrorCallback& error_callback,
bool success);
// Object path of the D-Bus characteristic object.
dbus::ObjectPath object_path_;
// The GATT service this GATT characteristic belongs to.
BluetoothRemoteGattServiceChromeOS* service_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<BluetoothRemoteGattCharacteristicChromeOS>
weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicChromeOS);
};
} // namespace chromeos
#endif // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
...@@ -5,11 +5,27 @@ ...@@ -5,11 +5,27 @@
#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "chromeos/dbus/bluetooth_gatt_service_client.h" #include "chromeos/dbus/bluetooth_gatt_service_client.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
namespace chromeos { namespace chromeos {
namespace {
// Stream operator for logging vector<uint8>.
std::ostream& operator<<(std::ostream& out, const std::vector<uint8> bytes) {
out << "[";
for (std::vector<uint8>::const_iterator iter = bytes.begin();
iter != bytes.end(); ++iter) {
out << base::StringPrintf("%02X", *iter);
}
return out << "]";
}
} // namespace
BluetoothRemoteGattServiceChromeOS::BluetoothRemoteGattServiceChromeOS( BluetoothRemoteGattServiceChromeOS::BluetoothRemoteGattServiceChromeOS(
BluetoothDeviceChromeOS* device, BluetoothDeviceChromeOS* device,
const dbus::ObjectPath& object_path) const dbus::ObjectPath& object_path)
...@@ -19,11 +35,47 @@ BluetoothRemoteGattServiceChromeOS::BluetoothRemoteGattServiceChromeOS( ...@@ -19,11 +35,47 @@ BluetoothRemoteGattServiceChromeOS::BluetoothRemoteGattServiceChromeOS(
VLOG(1) << "Creating remote GATT service with identifier: " VLOG(1) << "Creating remote GATT service with identifier: "
<< object_path.value() << ", UUID: " << GetUUID().canonical_value(); << object_path.value() << ", UUID: " << GetUUID().canonical_value();
DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this); DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this);
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
AddObserver(this);
// Add all known GATT characteristics.
const std::vector<dbus::ObjectPath> gatt_chars =
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
GetCharacteristics();
for (std::vector<dbus::ObjectPath>::const_iterator iter = gatt_chars.begin();
iter != gatt_chars.end(); ++iter)
GattCharacteristicAdded(*iter);
} }
BluetoothRemoteGattServiceChromeOS::~BluetoothRemoteGattServiceChromeOS() { BluetoothRemoteGattServiceChromeOS::~BluetoothRemoteGattServiceChromeOS() {
DBusThreadManager::Get()->GetBluetoothGattServiceClient()-> DBusThreadManager::Get()->GetBluetoothGattServiceClient()->
RemoveObserver(this); RemoveObserver(this);
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
RemoveObserver(this);
// Clean up all the characteristics. Copy the characteristics list here and
// clear the original so that when we send GattCharacteristicRemoved(),
// GetCharacteristics() returns no characteristics.
CharacteristicMap characteristics = characteristics_;
characteristics_.clear();
for (CharacteristicMap::iterator iter = characteristics.begin();
iter != characteristics.end(); ++iter) {
FOR_EACH_OBSERVER(device::BluetoothGattService::Observer, observers_,
GattCharacteristicRemoved(this, iter->second));
delete iter->second;
}
}
void BluetoothRemoteGattServiceChromeOS::AddObserver(
device::BluetoothGattService::Observer* observer) {
DCHECK(observer);
observers_.AddObserver(observer);
}
void BluetoothRemoteGattServiceChromeOS::RemoveObserver(
device::BluetoothGattService::Observer* observer) {
DCHECK(observer);
observers_.RemoveObserver(observer);
} }
std::string BluetoothRemoteGattServiceChromeOS::GetIdentifier() const { std::string BluetoothRemoteGattServiceChromeOS::GetIdentifier() const {
...@@ -50,26 +102,30 @@ bool BluetoothRemoteGattServiceChromeOS::IsPrimary() const { ...@@ -50,26 +102,30 @@ bool BluetoothRemoteGattServiceChromeOS::IsPrimary() const {
return properties->primary.value(); return properties->primary.value();
} }
const std::vector<device::BluetoothGattCharacteristic*>& std::vector<device::BluetoothGattCharacteristic*>
BluetoothRemoteGattServiceChromeOS::GetCharacteristics() const { BluetoothRemoteGattServiceChromeOS::GetCharacteristics() const {
return characteristics_; std::vector<device::BluetoothGattCharacteristic*> characteristics;
for (CharacteristicMap::const_iterator iter = characteristics_.begin();
iter != characteristics_.end(); ++iter) {
characteristics.push_back(iter->second);
}
return characteristics;
} }
const std::vector<device::BluetoothGattService*>& std::vector<device::BluetoothGattService*>
BluetoothRemoteGattServiceChromeOS::GetIncludedServices() const { BluetoothRemoteGattServiceChromeOS::GetIncludedServices() const {
return includes_; // TODO(armansito): Return the actual included services here.
return std::vector<device::BluetoothGattService*>();
} }
void BluetoothRemoteGattServiceChromeOS::AddObserver( device::BluetoothGattCharacteristic*
device::BluetoothGattService::Observer* observer) { BluetoothRemoteGattServiceChromeOS::GetCharacteristic(
DCHECK(observer); const std::string& identifier) {
observers_.AddObserver(observer); CharacteristicMap::const_iterator iter =
} characteristics_.find(dbus::ObjectPath(identifier));
if (iter == characteristics_.end())
void BluetoothRemoteGattServiceChromeOS::RemoveObserver( return NULL;
device::BluetoothGattService::Observer* observer) { return iter->second;
DCHECK(observer);
observers_.RemoveObserver(observer);
} }
bool BluetoothRemoteGattServiceChromeOS::AddCharacteristic( bool BluetoothRemoteGattServiceChromeOS::AddCharacteristic(
...@@ -105,4 +161,84 @@ void BluetoothRemoteGattServiceChromeOS::GattServicePropertyChanged( ...@@ -105,4 +161,84 @@ void BluetoothRemoteGattServiceChromeOS::GattServicePropertyChanged(
GattServiceChanged(this)); GattServiceChanged(this));
} }
void BluetoothRemoteGattServiceChromeOS::GattCharacteristicAdded(
const dbus::ObjectPath& object_path) {
if (characteristics_.find(object_path) != characteristics_.end()) {
VLOG(1) << "Remote GATT characteristic already exists: "
<< object_path.value();
return;
}
BluetoothGattCharacteristicClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
GetProperties(object_path);
DCHECK(properties);
if (properties->service.value() != object_path_) {
VLOG(2) << "Remote GATT characteristic does not belong to this service.";
return;
}
VLOG(1) << "Adding new remote GATT characteristic for GATT service: "
<< GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
BluetoothRemoteGattCharacteristicChromeOS* characteristic =
new BluetoothRemoteGattCharacteristicChromeOS(this, object_path);
characteristics_[object_path] = characteristic;
DCHECK(characteristic->GetIdentifier() == object_path.value());
DCHECK(characteristic->GetUUID().IsValid());
FOR_EACH_OBSERVER(device::BluetoothGattService::Observer, observers_,
GattCharacteristicAdded(this, characteristic));
FOR_EACH_OBSERVER(device::BluetoothGattService::Observer, observers_,
GattServiceChanged(this));
}
void BluetoothRemoteGattServiceChromeOS::GattCharacteristicRemoved(
const dbus::ObjectPath& object_path) {
CharacteristicMap::iterator iter = characteristics_.find(object_path);
if (iter == characteristics_.end()) {
VLOG(2) << "Unknown GATT characteristic removed: " << object_path.value();
return;
}
VLOG(1) << "Removing remote GATT characteristic from service: "
<< GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
BluetoothRemoteGattCharacteristicChromeOS* characteristic = iter->second;
DCHECK(characteristic->object_path() == object_path);
characteristics_.erase(iter);
FOR_EACH_OBSERVER(device::BluetoothGattService::Observer, observers_,
GattCharacteristicRemoved(this, characteristic));
FOR_EACH_OBSERVER(device::BluetoothGattService::Observer, observers_,
GattServiceChanged(this));
delete characteristic;
}
void BluetoothRemoteGattServiceChromeOS::GattCharacteristicPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
CharacteristicMap::iterator iter = characteristics_.find(object_path);
if (iter == characteristics_.end()) {
VLOG(2) << "Unknown GATT characteristic property changed: "
<< object_path.value();
return;
}
// Ignore all property changes except for "Value".
BluetoothGattCharacteristicClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
GetProperties(object_path);
DCHECK(properties);
if (property_name != properties->value.name())
return;
VLOG(1) << "GATT characteristic value has changed: " << object_path.value()
<< ": " << properties->value.value();
FOR_EACH_OBSERVER(device::BluetoothGattService::Observer, observers_,
GattCharacteristicValueChanged(this, iter->second,
properties->value.value()));
}
} // namespace chromeos } // namespace chromeos
...@@ -5,11 +5,13 @@ ...@@ -5,11 +5,13 @@
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_CHROMEOS_H_ #ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_CHROMEOS_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_CHROMEOS_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_CHROMEOS_H_
#include <map>
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
#include "chromeos/dbus/bluetooth_gatt_service_client.h" #include "chromeos/dbus/bluetooth_gatt_service_client.h"
#include "dbus/object_path.h" #include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_gatt_service.h" #include "device/bluetooth/bluetooth_gatt_service.h"
...@@ -24,26 +26,30 @@ class BluetoothGattCharacteristic; ...@@ -24,26 +26,30 @@ class BluetoothGattCharacteristic;
namespace chromeos { namespace chromeos {
class BluetoothDeviceChromeOS; class BluetoothDeviceChromeOS;
class BluetoothRemoteGattCharacteristicChromeOS;
// The BluetoothRemoteGattServiceChromeOS class implements BluetootGattService // The BluetoothRemoteGattServiceChromeOS class implements BluetootGattService
// for remote GATT services on the the Chrome OS platform. // for remote GATT services on the the Chrome OS platform.
class BluetoothRemoteGattServiceChromeOS class BluetoothRemoteGattServiceChromeOS
: public device::BluetoothGattService, : public device::BluetoothGattService,
public BluetoothGattServiceClient::Observer { public BluetoothGattServiceClient::Observer,
public BluetoothGattCharacteristicClient::Observer {
public: public:
// device::BluetoothGattService overrides. // device::BluetoothGattService overrides.
virtual void AddObserver(
device::BluetoothGattService::Observer* observer) OVERRIDE;
virtual void RemoveObserver(
device::BluetoothGattService::Observer* observer) OVERRIDE;
virtual std::string GetIdentifier() const OVERRIDE; virtual std::string GetIdentifier() const OVERRIDE;
virtual device::BluetoothUUID GetUUID() const OVERRIDE; virtual device::BluetoothUUID GetUUID() const OVERRIDE;
virtual bool IsLocal() const OVERRIDE; virtual bool IsLocal() const OVERRIDE;
virtual bool IsPrimary() const OVERRIDE; virtual bool IsPrimary() const OVERRIDE;
virtual const std::vector<device::BluetoothGattCharacteristic*>& virtual std::vector<device::BluetoothGattCharacteristic*>
GetCharacteristics() const OVERRIDE; GetCharacteristics() const OVERRIDE;
virtual const std::vector<device::BluetoothGattService*>& virtual std::vector<device::BluetoothGattService*>
GetIncludedServices() const OVERRIDE; GetIncludedServices() const OVERRIDE;
virtual void AddObserver( virtual device::BluetoothGattCharacteristic* GetCharacteristic(
device::BluetoothGattService::Observer* observer) OVERRIDE; const std::string& identifier) OVERRIDE;
virtual void RemoveObserver(
device::BluetoothGattService::Observer* observer) OVERRIDE;
virtual bool AddCharacteristic( virtual bool AddCharacteristic(
device::BluetoothGattCharacteristic* characteristic) OVERRIDE; device::BluetoothGattCharacteristic* characteristic) OVERRIDE;
virtual bool AddIncludedService( virtual bool AddIncludedService(
...@@ -68,6 +74,15 @@ class BluetoothRemoteGattServiceChromeOS ...@@ -68,6 +74,15 @@ class BluetoothRemoteGattServiceChromeOS
const dbus::ObjectPath& object_path, const dbus::ObjectPath& object_path,
const std::string& property_name) OVERRIDE; const std::string& property_name) OVERRIDE;
// BluetoothGattCharacteristicClient::Observer override.
virtual void GattCharacteristicAdded(
const dbus::ObjectPath& object_path) OVERRIDE;
virtual void GattCharacteristicRemoved(
const dbus::ObjectPath& object_path) OVERRIDE;
virtual void GattCharacteristicPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) OVERRIDE;
// Object path of the GATT service. // Object path of the GATT service.
dbus::ObjectPath object_path_; dbus::ObjectPath object_path_;
...@@ -77,11 +92,13 @@ class BluetoothRemoteGattServiceChromeOS ...@@ -77,11 +92,13 @@ class BluetoothRemoteGattServiceChromeOS
// The device this GATT service belongs to. // The device this GATT service belongs to.
BluetoothDeviceChromeOS* device_; BluetoothDeviceChromeOS* device_;
// The list of characteristics that belong to this service. // Mapping from GATT characteristic object paths to characteristic objects.
std::vector<device::BluetoothGattCharacteristic*> characteristics_; // owned by this service. Since the Chrome OS implementation uses object
// paths as unique identifiers, we also use this mapping to return
// The list of GATT services included by this service. // characteristics by identifier.
std::vector<device::BluetoothGattService*> includes_; typedef std::map<dbus::ObjectPath, BluetoothRemoteGattCharacteristicChromeOS*>
CharacteristicMap;
CharacteristicMap characteristics_;
// Note: This should remain the last member so it'll be destroyed and // Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed. // invalidate its weak pointers before any other members are destroyed.
......
...@@ -98,4 +98,8 @@ bool BluetoothUUID::operator!=(const BluetoothUUID& uuid) const { ...@@ -98,4 +98,8 @@ bool BluetoothUUID::operator!=(const BluetoothUUID& uuid) const {
return canonical_value_ != uuid.canonical_value_; return canonical_value_ != uuid.canonical_value_;
} }
void PrintTo(const BluetoothUUID& uuid, std::ostream* out) {
*out << uuid.canonical_value();
}
} // namespace device } // namespace device
...@@ -89,6 +89,9 @@ class BluetoothUUID { ...@@ -89,6 +89,9 @@ class BluetoothUUID {
std::string canonical_value_; std::string canonical_value_;
}; };
// This is required by gtest to print a readable output on test failures.
void PrintTo(const BluetoothUUID& uuid, std::ostream* out);
} // namespace device } // namespace device
#endif // DEVICE_BLUETOOTH_BLUETOOTH_UUID_H_ #endif // DEVICE_BLUETOOTH_BLUETOOTH_UUID_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment