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

Unified Diff: components/arc/bluetooth/arc_bluetooth_bridge.cc

Issue 2104043002: arc: bluetooth: Implement Gatt Server add/delete/start/stop service (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gs1
Patch Set: rebase Created 4 years, 5 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: components/arc/bluetooth/arc_bluetooth_bridge.cc
diff --git a/components/arc/bluetooth/arc_bluetooth_bridge.cc b/components/arc/bluetooth/arc_bluetooth_bridge.cc
index 46bfa1353f11a921f28f4c92d8212a0d4294c5b3..17ddb50b4d881a08d5691f3bcc6f2cbdec0405be 100644
--- a/components/arc/bluetooth/arc_bluetooth_bridge.cc
+++ b/components/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -60,6 +60,83 @@ constexpr uint32_t kGattWritePermission =
BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
BluetoothGattCharacteristic::Permission::
PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED;
+constexpr int32_t kInvalidGattAttributeHandle = -1;
+
+using GattStatusCallback =
+ base::Callback<void(arc::mojom::BluetoothGattStatus)>;
+using GattReadCallback =
+ base::Callback<void(arc::mojom::BluetoothGattValuePtr)>;
+
+// Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
+// We want to convert last digit of the identifier to int in base 16
palmer 2016/07/22 02:56:09 Nit: Correct the comment: "Convert the last 4 char
puthik_chromium 2016/07/22 21:48:16 Done.
+int ConvertGattIdentifierToId(const std::string identifier) {
+ return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16);
palmer 2016/07/22 02:56:10 If stoi fails (e.g. because the characters were no
puthik_chromium 2016/07/22 21:48:16 We rely on BlueZ implementation that the character
+}
+
+// Create GattDBElement and fill in common data for
+// Gatt Service/Characteristic/Descriptor.
+template <class RemoteGattAttribute>
+arc::mojom::BluetoothGattDBElementPtr CreateGattDBElement(
+ const arc::mojom::BluetoothGattDBAttributeType type,
+ const RemoteGattAttribute* gatt_attr) {
palmer 2016/07/22 02:56:09 Style nit: Similar comment as before: My preferenc
puthik_chromium 2016/07/22 21:48:16 Done.
+ arc::mojom::BluetoothGattDBElementPtr element =
+ arc::mojom::BluetoothGattDBElement::New();
+ element->type = type;
+ element->uuid = arc::mojom::BluetoothUUID::From(gatt_attr->GetUUID());
+ element->id = element->attribute_handle = element->start_handle =
+ element->end_handle =
+ ConvertGattIdentifierToId(gatt_attr->GetIdentifier());
+ element->properties = 0;
+ return element;
+}
+
+// Find Gatt Service/Characteristic/Descriptor from std::vector using UUID.
palmer 2016/07/22 02:56:10 I might rewrite this comment to use the argument n
puthik_chromium 2016/07/22 21:48:16 Removed
+template <class RemoteGattAttribute>
+RemoteGattAttribute* FindGattAttributeFromUuid(
palmer 2016/07/22 02:56:09 I'd rename this to |FindGattAttributeByUuid|. (We
puthik_chromium 2016/07/22 21:48:16 Done.
+ const std::vector<RemoteGattAttribute*>& gatt_attrs,
palmer 2016/07/22 02:56:10 Style nit: |attributes|.
puthik_chromium 2016/07/22 21:48:16 Done.
+ const BluetoothUUID& uuid) {
+ auto it = std::find_if(
+ gatt_attrs.begin(), gatt_attrs.end(),
+ [uuid](RemoteGattAttribute* attr) { return attr->GetUUID() == uuid; });
+ if (it == gatt_attrs.end())
palmer 2016/07/22 02:56:09 Style nit: You could shorten this to: return it
puthik_chromium 2016/07/22 21:48:16 Done. This is more concise.
+ return nullptr;
+ return *it;
+}
+
+// Common success callback for GATT operations that only need to report
+// GattStatus back to Android.
+void OnGattOperationDone(const GattStatusCallback& callback) {
+ callback.Run(arc::mojom::BluetoothGattStatus::GATT_SUCCESS);
+}
+
+// Common error callback for GATT operations that only need to report
+// GattStatus back to Android.
+void OnGattOperationError(const GattStatusCallback& callback,
+ BluetoothGattService::GattErrorCode error_code) {
+ callback.Run(mojo::ConvertTo<arc::mojom::BluetoothGattStatus>(error_code));
+}
+
+// Common success callback for ReadGattCharacteristic and ReadGattDescriptor
+void OnGattReadDone(const GattReadCallback& callback,
+ const std::vector<uint8_t>& result) {
+ arc::mojom::BluetoothGattValuePtr gattValue =
+ arc::mojom::BluetoothGattValue::New();
+ gattValue->status = arc::mojom::BluetoothGattStatus::GATT_SUCCESS;
+ gattValue->value = mojo::Array<uint8_t>::From(result);
+ callback.Run(std::move(gattValue));
+}
+
+// Common error callback for ReadGattCharacteristic and ReadGattDescriptor
+void OnGattReadError(const GattReadCallback& callback,
+ BluetoothGattService::GattErrorCode error_code) {
+ arc::mojom::BluetoothGattValuePtr gattValue =
+ arc::mojom::BluetoothGattValue::New();
+ gattValue->status =
+ mojo::ConvertTo<arc::mojom::BluetoothGattStatus>(error_code);
+ gattValue->value = nullptr;
+ callback.Run(std::move(gattValue));
+}
+
} // namespace
namespace arc {
@@ -78,6 +155,8 @@ ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service)
}
ArcBluetoothBridge::~ArcBluetoothBridge() {
+ DCHECK(CalledOnValidThread());
+
arc_bridge_service()->bluetooth()->RemoveObserver(this);
if (bluetooth_adapter_)
@@ -86,6 +165,8 @@ ArcBluetoothBridge::~ArcBluetoothBridge() {
void ArcBluetoothBridge::OnAdapterInitialized(
scoped_refptr<BluetoothAdapter> adapter) {
+ DCHECK(CalledOnValidThread());
+
// We can downcast here because we are always running on Chrome OS, and
// so our adapter uses BlueZ.
bluetooth_adapter_ =
@@ -106,6 +187,8 @@ void ArcBluetoothBridge::OnInstanceReady() {
void ArcBluetoothBridge::AdapterPresentChanged(BluetoothAdapter* adapter,
bool present) {
+ DCHECK(CalledOnValidThread());
+
// If the adapter goes away, remove ourselves as an observer.
if (!present && adapter == bluetooth_adapter_) {
adapter->RemoveObserver(this);
@@ -695,6 +778,7 @@ void ArcBluetoothBridge::SearchService(mojom::BluetoothAddressPtr remote_addr) {
void ArcBluetoothBridge::OnStartLEListenDone(
const StartLEListenCallback& callback,
scoped_refptr<BluetoothAdvertisement> advertisement) {
+ DCHECK(CalledOnValidThread());
advertisment_ = advertisement;
callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
}
@@ -702,11 +786,13 @@ void ArcBluetoothBridge::OnStartLEListenDone(
void ArcBluetoothBridge::OnStartLEListenError(
const StartLEListenCallback& callback,
BluetoothAdvertisement::ErrorCode error_code) {
+ DCHECK(CalledOnValidThread());
advertisment_ = nullptr;
callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
}
void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) {
+ DCHECK(CalledOnValidThread());
std::unique_ptr<BluetoothAdvertisement::Data> adv_data =
base::WrapUnique(new BluetoothAdvertisement::Data(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST));
@@ -719,6 +805,7 @@ void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) {
void ArcBluetoothBridge::OnStopLEListenDone(
const StopLEListenCallback& callback) {
+ DCHECK(CalledOnValidThread());
advertisment_ = nullptr;
callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
}
@@ -726,6 +813,7 @@ void ArcBluetoothBridge::OnStopLEListenDone(
void ArcBluetoothBridge::OnStopLEListenError(
const StopLEListenCallback& callback,
BluetoothAdvertisement::ErrorCode error_code) {
+ DCHECK(CalledOnValidThread());
advertisment_ = nullptr;
callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
}
@@ -743,30 +831,6 @@ void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) {
weak_factory_.GetWeakPtr(), callback));
}
-// Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
-// We want to convert last digit of the identifier to int in base 16
-int ArcBluetoothBridge::ConvertGattIdentifierToId(
- const std::string identifier) const {
- return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16);
-}
-
-// Create GattDBElement and fill in common data for
-// Gatt Service/Characteristic/Descriptor.
-template <class T>
-mojom::BluetoothGattDBElementPtr ArcBluetoothBridge::CreateGattDBElement(
- const mojom::BluetoothGattDBAttributeType type,
- const T* gattObject) const {
- mojom::BluetoothGattDBElementPtr element =
- mojom::BluetoothGattDBElement::New();
- element->type = type;
- element->uuid = mojom::BluetoothUUID::From(gattObject->GetUUID());
- element->id = element->attribute_handle = element->start_handle =
- element->end_handle =
- ConvertGattIdentifierToId(gattObject->GetIdentifier());
- element->properties = 0;
- return element;
-}
-
void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
if (!HasBluetoothInstance())
return;
@@ -775,8 +839,7 @@ void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
mojo::Array<mojom::BluetoothGattDBElementPtr> db;
for (auto* service : device->GetGattServices()) {
- mojom::BluetoothGattDBElementPtr service_element = CreateGattDBElement<
- device::BluetoothRemoteGattService>(
+ mojom::BluetoothGattDBElementPtr service_element = CreateGattDBElement(
service->IsPrimary()
? mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE
: mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE,
@@ -795,14 +858,14 @@ void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
for (auto* characteristic : characteristics) {
mojom::BluetoothGattDBElementPtr characteristic_element =
- CreateGattDBElement<device::BluetoothRemoteGattCharacteristic>(
+ CreateGattDBElement(
mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC,
characteristic);
characteristic_element->properties = characteristic->GetProperties();
db.push_back(std::move(characteristic_element));
for (auto* descriptor : characteristic->GetDescriptors()) {
- db.push_back(CreateGattDBElement<device::BluetoothRemoteGattDescriptor>(
+ db.push_back(CreateGattDBElement(
mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR,
descriptor));
}
@@ -813,18 +876,6 @@ void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
std::move(remote_addr), std::move(db));
}
-// Find Gatt Service/Characteristic/Descriptor from std::vector from UUID.
-template <class T>
-T* ArcBluetoothBridge::FindGattObjectFromUuid(
- const std::vector<T*> gatt_objs,
- const device::BluetoothUUID uuid) const {
- auto it = std::find_if(gatt_objs.begin(), gatt_objs.end(),
- [&](T* obj) { return obj->GetUUID() == uuid; });
- if (it == gatt_objs.end())
- return nullptr;
- return *it;
-}
-
BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
@@ -838,14 +889,13 @@ BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic(
if (!device)
return nullptr;
- BluetoothRemoteGattService* service =
- FindGattObjectFromUuid<BluetoothRemoteGattService>(
- device->GetGattServices(), service_id->id->uuid.To<BluetoothUUID>());
+ BluetoothRemoteGattService* service = FindGattAttributeFromUuid(
+ device->GetGattServices(), service_id->id->uuid.To<BluetoothUUID>());
if (!service)
return nullptr;
- return FindGattObjectFromUuid<BluetoothRemoteGattCharacteristic>(
- service->GetCharacteristics(), char_id->uuid.To<BluetoothUUID>());
+ return FindGattAttributeFromUuid(service->GetCharacteristics(),
+ char_id->uuid.To<BluetoothUUID>());
}
BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor(
@@ -858,40 +908,8 @@ BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor(
if (!characteristic)
return nullptr;
- return FindGattObjectFromUuid<BluetoothRemoteGattDescriptor>(
- characteristic->GetDescriptors(), desc_id->uuid.To<BluetoothUUID>());
-}
-
-// Same callback for both ReadGattCharacteristic and ReadGattDescriptor
-void ArcBluetoothBridge::OnGattReadDone(
- const GattReadCallback& callback,
- const std::vector<uint8_t>& result) const {
- mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
- gattValue->status = mojom::BluetoothGattStatus::GATT_SUCCESS;
- gattValue->value = mojo::Array<uint8_t>::From(result);
- callback.Run(std::move(gattValue));
-}
-
-void ArcBluetoothBridge::OnGattReadError(
- const GattReadCallback& callback,
- BluetoothGattService::GattErrorCode error_code) const {
- mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
- gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code);
- gattValue->value = nullptr;
-
- callback.Run(std::move(gattValue));
-}
-
-// Same callback for both WriteGattCharacteristic and WriteGattDescriptor
-void ArcBluetoothBridge::OnGattWriteDone(
- const GattWriteCallback& callback) const {
- callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
-}
-
-void ArcBluetoothBridge::OnGattWriteError(
- const GattWriteCallback& callback,
- BluetoothGattService::GattErrorCode error_code) const {
- callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
+ return FindGattAttributeFromUuid(characteristic->GetDescriptors(),
+ desc_id->uuid.To<BluetoothUUID>());
}
void ArcBluetoothBridge::ReadGattCharacteristic(
@@ -905,10 +923,8 @@ void ArcBluetoothBridge::ReadGattCharacteristic(
DCHECK(characteristic->GetPermissions() & kGattReadPermission);
characteristic->ReadRemoteCharacteristic(
- base::Bind(&ArcBluetoothBridge::OnGattReadDone,
- weak_factory_.GetWeakPtr(), callback),
- base::Bind(&ArcBluetoothBridge::OnGattReadError,
- weak_factory_.GetWeakPtr(), callback));
+ base::Bind(&OnGattReadDone, callback),
+ base::Bind(&OnGattReadError, callback));
}
void ArcBluetoothBridge::WriteGattCharacteristic(
@@ -924,10 +940,8 @@ void ArcBluetoothBridge::WriteGattCharacteristic(
characteristic->WriteRemoteCharacteristic(
value->value.To<std::vector<uint8_t>>(),
- base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
- weak_factory_.GetWeakPtr(), callback),
- base::Bind(&ArcBluetoothBridge::OnGattWriteError,
- weak_factory_.GetWeakPtr(), callback));
+ base::Bind(&OnGattOperationDone, callback),
+ base::Bind(&OnGattOperationError, callback));
}
void ArcBluetoothBridge::ReadGattDescriptor(
@@ -942,11 +956,8 @@ void ArcBluetoothBridge::ReadGattDescriptor(
DCHECK(descriptor);
DCHECK(descriptor->GetPermissions() & kGattReadPermission);
- descriptor->ReadRemoteDescriptor(
- base::Bind(&ArcBluetoothBridge::OnGattReadDone,
- weak_factory_.GetWeakPtr(), callback),
- base::Bind(&ArcBluetoothBridge::OnGattReadError,
- weak_factory_.GetWeakPtr(), callback));
+ descriptor->ReadRemoteDescriptor(base::Bind(&OnGattReadDone, callback),
+ base::Bind(&OnGattReadError, callback));
}
void ArcBluetoothBridge::WriteGattDescriptor(
@@ -971,37 +982,25 @@ void ArcBluetoothBridge::WriteGattDescriptor(
// TODO(http://crbug.com/622832)
if (descriptor->GetUUID() ==
BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) {
- OnGattWriteDone(callback);
+ OnGattOperationDone(callback);
return;
}
descriptor->WriteRemoteDescriptor(
value->value.To<std::vector<uint8_t>>(),
- base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
- weak_factory_.GetWeakPtr(), callback),
- base::Bind(&ArcBluetoothBridge::OnGattWriteError,
- weak_factory_.GetWeakPtr(), callback));
+ base::Bind(&OnGattOperationDone, callback),
+ base::Bind(&OnGattOperationError, callback));
}
void ArcBluetoothBridge::OnGattNotifyStartDone(
const RegisterForGattNotificationCallback& callback,
const std::string char_string_id,
std::unique_ptr<BluetoothGattNotifySession> notify_session) {
+ DCHECK(CalledOnValidThread());
notification_session_[char_string_id] = std::move(notify_session);
callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
}
-void ArcBluetoothBridge::OnGattNotifyStartError(
- const RegisterForGattNotificationCallback& callback,
- BluetoothGattService::GattErrorCode error_code) const {
- callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
-}
-
-void ArcBluetoothBridge::OnGattNotifyStopDone(
- const DeregisterForGattNotificationCallback& callback) const {
- callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
-}
-
void ArcBluetoothBridge::RegisterForGattNotification(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
@@ -1024,8 +1023,7 @@ void ArcBluetoothBridge::RegisterForGattNotification(
base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone,
weak_factory_.GetWeakPtr(), callback,
characteristic->GetIdentifier()),
- base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError,
- weak_factory_.GetWeakPtr(), callback));
+ base::Bind(&OnGattOperationError, callback));
}
void ArcBluetoothBridge::DeregisterForGattNotification(
@@ -1033,6 +1031,8 @@ void ArcBluetoothBridge::DeregisterForGattNotification(
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id,
const DeregisterForGattNotificationCallback& callback) {
+ DCHECK(CalledOnValidThread());
+
BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
std::move(remote_addr), std::move(service_id), std::move(char_id));
@@ -1050,8 +1050,7 @@ void ArcBluetoothBridge::DeregisterForGattNotification(
std::unique_ptr<BluetoothGattNotifySession> notify =
std::move(notification_session_[char_id_str]);
notification_session_.erase(char_id_str);
- notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone,
- weak_factory_.GetWeakPtr(), callback));
+ notify->Stop(base::Bind(&OnGattOperationDone, callback));
}
void ArcBluetoothBridge::ReadRemoteRssi(
@@ -1063,30 +1062,120 @@ void ArcBluetoothBridge::ReadRemoteRssi(
callback.Run(rssi);
}
+template <class LocalGattAttribute>
+int32_t ArcBluetoothBridge::CreateGattAttributeHandle(
+ LocalGattAttribute* gatt_attr) {
+ DCHECK(CalledOnValidThread());
+ if (!gatt_attr)
+ return kInvalidGattAttributeHandle;
+ int32_t handle = next_gatt_server_attribute_handle();
+ const std::string& identifier = gatt_attr->GetIdentifier();
+ gatt_identifier_[handle] = identifier;
palmer 2016/07/22 02:56:10 Style nit: You could just do gatt_identifier_[h
puthik_chromium 2016/07/22 21:48:16 Won't fix. identifier will be used in next CL.
+ return handle;
+}
+
void ArcBluetoothBridge::AddService(mojom::BluetoothGattServiceIDPtr service_id,
int32_t num_handles,
- const AddServiceCallback& callback) {}
+ const AddServiceCallback& callback) {
+ base::WeakPtr<BluetoothLocalGattService> service =
+ BluetoothLocalGattService::Create(
+ bluetooth_adapter_.get(), service_id->id->uuid.To<BluetoothUUID>(),
+ service_id->is_primary, nullptr /* included_service */,
+ this /* delegate */);
+ callback.Run(CreateGattAttributeHandle(service.get()));
+}
void ArcBluetoothBridge::AddCharacteristic(
int32_t service_handle,
mojom::BluetoothUUIDPtr uuid,
int32_t properties,
int32_t permissions,
- const AddCharacteristicCallback& callback) {}
+ const AddCharacteristicCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
+ base::WeakPtr<BluetoothLocalGattCharacteristic> characteristic =
+ BluetoothLocalGattCharacteristic::Create(
+ uuid.To<BluetoothUUID>(), properties, permissions,
+ bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]));
+ int32_t characteristic_handle =
+ CreateGattAttributeHandle(characteristic.get());
+ last_characteristic_[service_handle] = characteristic_handle;
+ callback.Run(characteristic_handle);
+}
void ArcBluetoothBridge::AddDescriptor(int32_t service_handle,
mojom::BluetoothUUIDPtr uuid,
int32_t permissions,
- const AddDescriptorCallback& callback) {}
+ const AddDescriptorCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ // Chrome automatically adds a CCC Descriptor to a characteristic when needed.
+ // We will generate a bogus handle for Android.
+ if (uuid.To<BluetoothUUID>() ==
+ BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) {
+ int32_t handle = next_gatt_server_attribute_handle();
+ callback.Run(handle);
+ return;
+ }
+
+ DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
+ BluetoothLocalGattService* service =
+ bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]);
+ DCHECK(service);
+ // Since the Android API does not give information about which characteristic
+ // is the parent of the new descriptor, we assume that it would be the last
+ // characteristic that was added to the given service. This matches the
+ // Android framework code at android/bluetooth/BluetoothGattServer.java#594.
+ // Link: https://goo.gl/cJZl1u
+ DCHECK(last_characteristic_.find(service_handle) !=
+ last_characteristic_.end());
+ int32_t last_characteristic_handle = last_characteristic_[service_handle];
+
+ DCHECK(gatt_identifier_.find(last_characteristic_handle) !=
+ gatt_identifier_.end());
+ BluetoothLocalGattCharacteristic* characteristic =
+ service->GetCharacteristic(gatt_identifier_[last_characteristic_handle]);
+ DCHECK(characteristic);
+
+ base::WeakPtr<BluetoothLocalGattDescriptor> descriptor =
+ BluetoothLocalGattDescriptor::Create(uuid.To<BluetoothUUID>(),
+ permissions, characteristic);
+ callback.Run(CreateGattAttributeHandle(descriptor.get()));
+}
void ArcBluetoothBridge::StartService(int32_t service_handle,
- const StartServiceCallback& callback) {}
+ const StartServiceCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
+ BluetoothLocalGattService* service =
+ bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]);
+ DCHECK(service);
+ service->Register(base::Bind(&OnGattOperationDone, callback),
+ base::Bind(&OnGattOperationError, callback));
+}
void ArcBluetoothBridge::StopService(int32_t service_handle,
- const StopServiceCallback& callback) {}
+ const StopServiceCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
+ BluetoothLocalGattService* service =
+ bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]);
+ DCHECK(service);
+ service->Unregister(base::Bind(&OnGattOperationDone, callback),
+ base::Bind(&OnGattOperationError, callback));
+}
void ArcBluetoothBridge::DeleteService(int32_t service_handle,
- const DeleteServiceCallback& callback) {}
+ const DeleteServiceCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
+ BluetoothLocalGattService* service =
+ bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]);
+ DCHECK(service);
+
+ service->Delete();
+ gatt_identifier_.erase(service_handle);
+ OnGattOperationDone(callback);
+}
void ArcBluetoothBridge::SendIndication(
int32_t attribute_handle,
@@ -1432,4 +1521,8 @@ bool ArcBluetoothBridge::CheckBluetoothInstanceVersion(
return false;
}
+bool ArcBluetoothBridge::CalledOnValidThread() {
+ return thread_checker_.CalledOnValidThread();
+}
+
} // namespace arc

Powered by Google App Engine
This is Rietveld 408576698