Revert 269361 "Fix WebURLLoaderImpl::Context leak if a pending r..."
[chromium-blink-merge.git] / device / bluetooth / bluetooth_remote_gatt_characteristic_chromeos.cc
blobbb175e3f375fb2df4f9006dd3ea056aed119443f
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
7 #include "base/logging.h"
8 #include "base/strings/stringprintf.h"
9 #include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
10 #include "chromeos/dbus/dbus_thread_manager.h"
11 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
12 #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
14 namespace chromeos {
16 namespace {
18 // Stream operator for logging vector<uint8>.
19 std::ostream& operator<<(std::ostream& out, const std::vector<uint8> bytes) {
20 out << "[";
21 for (std::vector<uint8>::const_iterator iter = bytes.begin();
22 iter != bytes.end(); ++iter) {
23 out << base::StringPrintf("%02X", *iter);
25 return out << "]";
28 } // namespace
30 BluetoothRemoteGattCharacteristicChromeOS::
31 BluetoothRemoteGattCharacteristicChromeOS(
32 BluetoothRemoteGattServiceChromeOS* service,
33 const dbus::ObjectPath& object_path)
34 : object_path_(object_path),
35 service_(service),
36 weak_ptr_factory_(this) {
37 VLOG(1) << "Creating remote GATT characteristic with identifier: "
38 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
39 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
40 AddObserver(this);
42 // Add all known GATT characteristic descriptors.
43 const std::vector<dbus::ObjectPath>& gatt_descs =
44 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
45 GetDescriptors();
46 for (std::vector<dbus::ObjectPath>::const_iterator iter = gatt_descs.begin();
47 iter != gatt_descs.end(); ++iter)
48 GattDescriptorAdded(*iter);
51 BluetoothRemoteGattCharacteristicChromeOS::
52 ~BluetoothRemoteGattCharacteristicChromeOS() {
53 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
54 RemoveObserver(this);
56 // Clean up all the descriptors. There isn't much point in notifying service
57 // observers for each descriptor that gets removed, so just delete them.
58 for (DescriptorMap::iterator iter = descriptors_.begin();
59 iter != descriptors_.end(); ++iter)
60 delete iter->second;
63 std::string BluetoothRemoteGattCharacteristicChromeOS::GetIdentifier() const {
64 return object_path_.value();
67 device::BluetoothUUID
68 BluetoothRemoteGattCharacteristicChromeOS::GetUUID() const {
69 BluetoothGattCharacteristicClient::Properties* properties =
70 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
71 GetProperties(object_path_);
72 DCHECK(properties);
73 return device::BluetoothUUID(properties->uuid.value());
76 bool BluetoothRemoteGattCharacteristicChromeOS::IsLocal() const {
77 return false;
80 const std::vector<uint8>&
81 BluetoothRemoteGattCharacteristicChromeOS::GetValue() const {
82 BluetoothGattCharacteristicClient::Properties* properties =
83 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
84 GetProperties(object_path_);
85 DCHECK(properties);
86 return properties->value.value();
89 device::BluetoothGattService*
90 BluetoothRemoteGattCharacteristicChromeOS::GetService() const {
91 return service_;
94 device::BluetoothGattCharacteristic::Properties
95 BluetoothRemoteGattCharacteristicChromeOS::GetProperties() const {
96 // TODO(armansito): Once BlueZ implements properties properly, return those
97 // values here.
98 return kPropertyNone;
101 device::BluetoothGattCharacteristic::Permissions
102 BluetoothRemoteGattCharacteristicChromeOS::GetPermissions() const {
103 // TODO(armansito): Once BlueZ defines the permissions, return the correct
104 // values here.
105 return kPermissionNone;
108 std::vector<device::BluetoothGattDescriptor*>
109 BluetoothRemoteGattCharacteristicChromeOS::GetDescriptors() const {
110 std::vector<device::BluetoothGattDescriptor*> descriptors;
111 for (DescriptorMap::const_iterator iter = descriptors_.begin();
112 iter != descriptors_.end(); ++iter)
113 descriptors.push_back(iter->second);
114 return descriptors;
117 device::BluetoothGattDescriptor*
118 BluetoothRemoteGattCharacteristicChromeOS::GetDescriptor(
119 const std::string& identifier) const {
120 DescriptorMap::const_iterator iter =
121 descriptors_.find(dbus::ObjectPath(identifier));
122 if (iter == descriptors_.end())
123 return NULL;
124 return iter->second;
127 bool BluetoothRemoteGattCharacteristicChromeOS::AddDescriptor(
128 device::BluetoothGattDescriptor* descriptor) {
129 VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic.";
130 return false;
133 bool BluetoothRemoteGattCharacteristicChromeOS::UpdateValue(
134 const std::vector<uint8>& value) {
135 VLOG(1) << "Cannot update the value of a remote GATT characteristic.";
136 return false;
139 void BluetoothRemoteGattCharacteristicChromeOS::ReadRemoteCharacteristic(
140 const ValueCallback& callback,
141 const ErrorCallback& error_callback) {
142 VLOG(1) << "Sending GATT characteristic read request to characteristic: "
143 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
144 << ".";
145 BluetoothGattCharacteristicClient::Properties* properties =
146 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
147 GetProperties(object_path_);
148 DCHECK(properties);
149 properties->value.Get(
150 base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnGetValue,
151 weak_ptr_factory_.GetWeakPtr(),
152 callback, error_callback));
155 void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic(
156 const std::vector<uint8>& new_value,
157 const base::Closure& callback,
158 const ErrorCallback& error_callback) {
159 VLOG(1) << "Sending GATT characteristic write request to characteristic: "
160 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
161 << ", with value: " << new_value << ".";
163 // Permission and bonding are handled by BlueZ so no need check it here.
164 if (new_value.empty()) {
165 VLOG(1) << "Nothing to write.";
166 error_callback.Run();
167 return;
170 BluetoothGattCharacteristicClient::Properties* properties =
171 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
172 GetProperties(object_path_);
173 DCHECK(properties);
174 properties->value.Set(
175 new_value,
176 base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnSetValue,
177 weak_ptr_factory_.GetWeakPtr(),
178 callback, error_callback));
181 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorAdded(
182 const dbus::ObjectPath& object_path) {
183 if (descriptors_.find(object_path) != descriptors_.end()) {
184 VLOG(1) << "Remote GATT characteristic descriptor already exists: "
185 << object_path.value();
186 return;
189 BluetoothGattDescriptorClient::Properties* properties =
190 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
191 GetProperties(object_path);
192 DCHECK(properties);
193 if (properties->characteristic.value() != object_path_) {
194 VLOG(2) << "Remote GATT descriptor does not belong to this characteristic.";
195 return;
198 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: "
199 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
201 BluetoothRemoteGattDescriptorChromeOS* descriptor =
202 new BluetoothRemoteGattDescriptorChromeOS(this, object_path);
203 descriptors_[object_path] = descriptor;
204 DCHECK(descriptor->GetIdentifier() == object_path.value());
205 DCHECK(descriptor->GetUUID().IsValid());
206 DCHECK(service_);
208 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */);
209 service_->NotifyServiceChanged();
212 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorRemoved(
213 const dbus::ObjectPath& object_path) {
214 DescriptorMap::iterator iter = descriptors_.find(object_path);
215 if (iter == descriptors_.end()) {
216 VLOG(2) << "Unknown descriptor removed: " << object_path.value();
217 return;
220 VLOG(1) << "Removing remote GATT descriptor from characteristic: "
221 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
223 BluetoothRemoteGattDescriptorChromeOS* descriptor = iter->second;
224 DCHECK(descriptor->object_path() == object_path);
225 descriptors_.erase(iter);
227 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, false /* added */);
228 delete descriptor;
230 DCHECK(service_);
232 service_->NotifyServiceChanged();
235 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorPropertyChanged(
236 const dbus::ObjectPath& object_path,
237 const std::string& property_name) {
238 DescriptorMap::const_iterator iter = descriptors_.find(object_path);
239 if (iter == descriptors_.end())
240 return;
242 // Ignore all property changes except for "Value".
243 BluetoothGattDescriptorClient::Properties* properties =
244 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
245 GetProperties(object_path);
246 DCHECK(properties);
247 if (property_name != properties->value.name())
248 return;
250 VLOG(1) << "GATT descriptor property changed: " << object_path.value()
251 << ", property: " << property_name;
253 DCHECK(service_);
255 service_->NotifyDescriptorValueChanged(
256 this, iter->second, properties->value.value());
259 void BluetoothRemoteGattCharacteristicChromeOS::OnGetValue(
260 const ValueCallback& callback,
261 const ErrorCallback& error_callback,
262 bool success) {
263 if (!success) {
264 VLOG(1) << "Failed to read the value from the remote characteristic.";
265 error_callback.Run();
266 return;
269 VLOG(1) << "Read value of remote characteristic.";
270 BluetoothGattCharacteristicClient::Properties* properties =
271 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
272 GetProperties(object_path_);
273 DCHECK(properties);
274 callback.Run(properties->value.value());
277 void BluetoothRemoteGattCharacteristicChromeOS::OnSetValue(
278 const base::Closure& callback,
279 const ErrorCallback& error_callback,
280 bool success) {
281 if (!success) {
282 VLOG(1) << "Failed to write the value of remote characteristic.";
283 error_callback.Run();
284 return;
287 VLOG(1) << "Wrote value of remote characteristic.";
288 callback.Run();
291 } // namespace chromeos