summaryrefslogtreecommitdiffstats
path: root/chromeos/dbus
diff options
context:
space:
mode:
authorarmansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-11 08:20:12 +0000
committerarmansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-11 08:20:12 +0000
commit2a46ef5d4a8fb7037def587b7927cd359561b296 (patch)
tree3972c42ee200f2ca0e2f6f8ef013ea4bb8e82d2d /chromeos/dbus
parentb5e5a42df4b992425cb8692d418dfc1aca1bc316 (diff)
downloadchromium_src-2a46ef5d4a8fb7037def587b7927cd359561b296.zip
chromium_src-2a46ef5d4a8fb7037def587b7927cd359561b296.tar.gz
chromium_src-2a46ef5d4a8fb7037def587b7927cd359561b296.tar.bz2
device/bluetooth: Add chromeos::BluetoothRemoteGattDescriptorChromeOS.
Added the chromeos::BluetoothRemoteGattDescriptorChromeOS class which implements a remote instance of device::BluetoothGattDescriptor for the Chrome OS platform. BUG=360266,340529 TEST=device_unittests Review URL: https://codereview.chromium.org/234443005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263194 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/dbus')
-rw-r--r--chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc20
-rw-r--r--chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h1
-rw-r--r--chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc115
-rw-r--r--chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h39
4 files changed, 166 insertions, 9 deletions
diff --git a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc b/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc
index 55784a9..dbbdcc3 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc
+++ b/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc
@@ -8,6 +8,8 @@
#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "base/time/time.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
@@ -207,12 +209,28 @@ void FakeBluetoothGattCharacteristicClient::ExposeHeartRateCharacteristics(
// be handled by BlueZ, automatically set up notifications for now.
ScheduleHeartRateMeasurementValueChange();
- // TODO(armansito): Add descriptors.
+ // Expose CCC descriptor for Heart Rate Measurement characteristic.
+ FakeBluetoothGattDescriptorClient* descriptor_client =
+ static_cast<FakeBluetoothGattDescriptorClient*>(
+ DBusThreadManager::Get()->GetBluetoothGattDescriptorClient());
+ dbus::ObjectPath ccc_path(descriptor_client->ExposeDescriptor(
+ dbus::ObjectPath(heart_rate_measurement_path_),
+ FakeBluetoothGattDescriptorClient::
+ kClientCharacteristicConfigurationUUID));
+ DCHECK(ccc_path.IsValid());
+ heart_rate_measurement_ccc_desc_path_ = ccc_path.value();
}
void FakeBluetoothGattCharacteristicClient::HideHeartRateCharacteristics() {
VLOG(2) << "Hiding fake Heart Rate characteristics.";
+ // Hide the descriptors.
+ FakeBluetoothGattDescriptorClient* descriptor_client =
+ static_cast<FakeBluetoothGattDescriptorClient*>(
+ DBusThreadManager::Get()->GetBluetoothGattDescriptorClient());
+ descriptor_client->HideDescriptor(
+ dbus::ObjectPath(heart_rate_measurement_ccc_desc_path_));
+
// Notify the observers before deleting the properties structures so that they
// can be accessed from the observer method.
NotifyCharacteristicRemoved(dbus::ObjectPath(heart_rate_measurement_path_));
diff --git a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h b/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h
index bd3d126..1ae77cb 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h
+++ b/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h
@@ -110,6 +110,7 @@ class CHROMEOS_EXPORT FakeBluetoothGattCharacteristicClient
// Object paths of the exposed characteristics. If a characteristic is not
// exposed, these will be empty.
std::string heart_rate_measurement_path_;
+ std::string heart_rate_measurement_ccc_desc_path_;
std::string body_sensor_location_path_;
std::string heart_rate_control_point_path_;
diff --git a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc b/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc
index f0846a8..4bb5255 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc
+++ b/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc
@@ -4,10 +4,18 @@
#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
+#include "base/bind.h"
+#include "base/logging.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
+const char FakeBluetoothGattDescriptorClient::
+ kClientCharacteristicConfigurationPathComponent[] = "desc0000";
+const char FakeBluetoothGattDescriptorClient::
+ kClientCharacteristicConfigurationUUID[] =
+ "00002902-0000-1000-8000-00805f9b34fb";
+
FakeBluetoothGattDescriptorClient::Properties::Properties(
const PropertyChangedCallback& callback)
: BluetoothGattDescriptorClient::Properties(
@@ -23,7 +31,7 @@ void FakeBluetoothGattDescriptorClient::Properties::Get(
dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) {
VLOG(1) << "Get " << property->name();
- callback.Run(false);
+ callback.Run(true);
}
void FakeBluetoothGattDescriptorClient::Properties::GetAll() {
@@ -33,14 +41,24 @@ void FakeBluetoothGattDescriptorClient::Properties::GetAll() {
void FakeBluetoothGattDescriptorClient::Properties::Set(
dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) {
- VLOG(1) << "Get " << property->name();
- callback.Run(false);
+ VLOG(1) << "Set " << property->name();
+ if (property->name() != value.name()) {
+ callback.Run(false);
+ return;
+ }
// TODO(armansito): Setting the "Value" property should be allowed based
// on permissions.
+ if (uuid.value() != kClientCharacteristicConfigurationUUID) {
+ callback.Run(false);
+ return;
+ }
+ callback.Run(true);
+ property->ReplaceValueWithSetValue();
}
-FakeBluetoothGattDescriptorClient::FakeBluetoothGattDescriptorClient() {
+FakeBluetoothGattDescriptorClient::FakeBluetoothGattDescriptorClient()
+ : weak_ptr_factory_(this) {
}
FakeBluetoothGattDescriptorClient::~FakeBluetoothGattDescriptorClient() {
@@ -59,13 +77,98 @@ void FakeBluetoothGattDescriptorClient::RemoveObserver(Observer* observer) {
std::vector<dbus::ObjectPath>
FakeBluetoothGattDescriptorClient::GetDescriptors() {
- return std::vector<dbus::ObjectPath>();
+ std::vector<dbus::ObjectPath> descriptors;
+ for (PropertiesMap::const_iterator iter = properties_.begin();
+ iter != properties_.end(); ++iter) {
+ descriptors.push_back(iter->first);
+ }
+ return descriptors;
}
FakeBluetoothGattDescriptorClient::Properties*
FakeBluetoothGattDescriptorClient::GetProperties(
const dbus::ObjectPath& object_path) {
- return NULL;
+ PropertiesMap::const_iterator iter = properties_.find(object_path);
+ if (iter == properties_.end())
+ return NULL;
+ return iter->second;
+}
+
+dbus::ObjectPath FakeBluetoothGattDescriptorClient::ExposeDescriptor(
+ const dbus::ObjectPath& characteristic_path,
+ const std::string& uuid) {
+ if (uuid != kClientCharacteristicConfigurationUUID) {
+ VLOG(2) << "Unsupported UUID: " << uuid;
+ return dbus::ObjectPath();
+ }
+
+ // CCC descriptor is the only one supported at the moment.
+ DCHECK(characteristic_path.IsValid());
+ dbus::ObjectPath object_path(
+ characteristic_path.value() + "/" +
+ kClientCharacteristicConfigurationPathComponent);
+ DCHECK(object_path.IsValid());
+ PropertiesMap::const_iterator iter = properties_.find(object_path);
+ if (iter != properties_.end()) {
+ VLOG(1) << "Descriptor already exposed: " << object_path.value();
+ return dbus::ObjectPath();
+ }
+
+ Properties* properties = new Properties(base::Bind(
+ &FakeBluetoothGattDescriptorClient::OnPropertyChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ object_path));
+ properties_[object_path] = properties;
+ properties->uuid.ReplaceValue(uuid);
+ properties->characteristic.ReplaceValue(characteristic_path);
+
+ std::vector<uint8> value;
+ value.push_back(0); // Notifications/Indications disabled.
+ value.push_back(0);
+ properties->value.ReplaceValue(value);
+
+ NotifyDescriptorAdded(object_path);
+
+ return object_path;
+}
+
+void FakeBluetoothGattDescriptorClient::HideDescriptor(
+ const dbus::ObjectPath& descriptor_path) {
+ PropertiesMap::iterator iter = properties_.find(descriptor_path);
+ if (iter == properties_.end()) {
+ VLOG(1) << "Descriptor not exposed: " << descriptor_path.value();
+ return;
+ }
+
+ NotifyDescriptorRemoved(descriptor_path);
+
+ delete iter->second;
+ properties_.erase(iter);
+}
+
+void FakeBluetoothGattDescriptorClient::OnPropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) {
+ VLOG(2) << "Descriptor property changed: " << object_path.value()
+ << ": " << property_name;
+
+ FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_,
+ GattDescriptorPropertyChanged(object_path, property_name));
+
+ // TODO(armansito): Implement CCC behavior (enable/disable notifications
+ // or indications characteristics).
+}
+
+void FakeBluetoothGattDescriptorClient::NotifyDescriptorAdded(
+ const dbus::ObjectPath& object_path) {
+ FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_,
+ GattDescriptorAdded(object_path));
+}
+
+void FakeBluetoothGattDescriptorClient::NotifyDescriptorRemoved(
+ const dbus::ObjectPath& object_path) {
+ FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_,
+ GattDescriptorRemoved(object_path));
}
} // namespace chromeos
diff --git a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h b/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h
index dd9f7af..3676983 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h
+++ b/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h
@@ -5,9 +5,14 @@
#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
+#include <map>
+#include <string>
+
+#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
+#include "dbus/object_path.h"
namespace chromeos {
@@ -42,13 +47,43 @@ class CHROMEOS_EXPORT FakeBluetoothGattDescriptorClient
virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
OVERRIDE;
+ // Makes the descriptor with the UUID |uuid| visible under the characteristic
+ // with object path |characteristic_path|. Descriptor object paths are
+ // hierarchical to their characteristics. |uuid| must belong to a descriptor
+ // for which there is a constant defined below, otherwise this method has no
+ // effect. Returns the object path of the created descriptor. In the no-op
+ // case, returns an invalid path.
+ dbus::ObjectPath ExposeDescriptor(const dbus::ObjectPath& characteristic_path,
+ const std::string& uuid);
+ void HideDescriptor(const dbus::ObjectPath& descriptor_path);
+
+ // Object path components and UUIDs of GATT characteristic descriptors.
+ static const char kClientCharacteristicConfigurationPathComponent[];
+ static const char kClientCharacteristicConfigurationUUID[];
+
private:
- // TODO(armansito): Add simulated descriptors, once BlueZ's behavior is
- // better defined.
+ // Property callback passed when we create Properties structures.
+ void OnPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& property_name);
+
+ // Notifies observers.
+ void NotifyDescriptorAdded(const dbus::ObjectPath& object_path);
+ void NotifyDescriptorRemoved(const dbus::ObjectPath& object_path);
+
+ // Mapping from object paths to Properties structures.
+ typedef std::map<dbus::ObjectPath, Properties*> PropertiesMap;
+ PropertiesMap properties_;
// List of observers interested in event notifications from us.
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<FakeBluetoothGattDescriptorClient>
+ weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattDescriptorClient);
};