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

Unified Diff: device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc

Issue 1712593002: bluetooth: android: Confirm the notify session after the descriptor has been written. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Vincent's comments Created 4 years, 10 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: device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
index d8d029900367defb7a0fc01af7d8895132b876fe..bb7e6696e7e55bfd7a930321243befbdd1541970 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
@@ -136,20 +136,60 @@ bool BluetoothRemoteGattCharacteristicAndroid::UpdateValue(
void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession(
const NotifySessionCallback& callback,
const ErrorCallback& error_callback) {
- if (Java_ChromeBluetoothRemoteGattCharacteristic_startNotifySession(
- AttachCurrentThread(), j_characteristic_.obj())) {
- // TODO(crbug.com/569664): Wait until descriptor write completes before
- // reporting success via calling |callback|.
- scoped_ptr<device::BluetoothGattNotifySession> notify_session(
- new BluetoothGattNotifySessionAndroid(instance_id_));
+ if (!pending_start_notify_calls_.empty()) {
ortuno 2016/03/04 17:39:47 Why are we allowing multiple notify session calls?
scheib 2016/03/11 03:17:31 Unlike a read or write that must happen serially,
+ pending_start_notify_calls_.push(std::make_pair(callback, error_callback));
+ return;
+ }
+
+ Properties properties = GetProperties();
+
+ bool hasNotify = properties & PROPERTY_NOTIFY;
+ bool hasIndicate = properties & PROPERTY_INDICATE;
+
+ if (!hasNotify && !hasIndicate) {
+ LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE";
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(error_callback,
+ BluetoothRemoteGattServiceAndroid::GATT_ERROR_FAILED));
ortuno 2016/03/04 17:39:47 I think this should be GATT_ERROR_NOT_SUPPORTED.
scheib 2016/03/11 03:17:31 Done.
+ return;
+ }
+
+ BluetoothGattDescriptor* descriptor = GetDescriptorForUUID(
+ BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid());
+
+ if (!descriptor) {
+ LOG(ERROR)
+ << "Could not find client characteristic configuration descriptor";
base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(callback, base::Passed(&notify_session)));
- } else {
+ FROM_HERE,
+ base::Bind(error_callback,
+ BluetoothRemoteGattServiceAndroid::GATT_ERROR_FAILED));
ortuno 2016/03/04 17:39:47 Same here. I think GATT_ERROR_NOT_SUPPORTED is mor
scheib 2016/03/11 03:17:31 Done.
+ return;
+ }
+
+ if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotification(
+ AttachCurrentThread(), j_characteristic_.obj(), true)) {
+ LOG(ERROR) << "Error enabling characteristic notification";
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(error_callback,
BluetoothRemoteGattServiceAndroid::GATT_ERROR_FAILED));
+ return;
}
+
+ std::vector<uint8_t> value;
ortuno 2016/03/04 17:39:47 nit: value(2) // The Client Characteristic Configu
scheib 2016/03/11 03:17:31 Done.
+ value.push_back(hasNotify ? 1 : 2);
+ value.push_back(0);
+
+ pending_start_notify_calls_.push(std::make_pair(callback, error_callback));
+ descriptor->WriteRemoteDescriptor(
+ value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid::
+ OnStartNotifySessionSuccess,
+ base::Unretained(this)),
ortuno 2016/03/04 17:39:47 Is this safe? I guess it is since the characterist
scheib 2016/03/11 03:17:31 Acknowledged.
+ base::Bind(
+ &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError,
+ base::Unretained(this)));
}
void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic(
@@ -211,6 +251,25 @@ void BluetoothRemoteGattCharacteristicAndroid::OnChanged(
adapter_->NotifyGattCharacteristicValueChanged(this, value_);
}
+void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() {
+ while (!pending_start_notify_calls_.empty()) {
scheib 2016/03/02 06:15:20 Protect against reentrant code by swapping the mem
ortuno 2016/03/04 17:39:47 I just realized how easy it is to miss this. Do we
scheib 2016/03/11 03:17:31 Not yet -- we should. Here's a new issue: https://
+ PendingStartNotifyCall callbacks = pending_start_notify_calls_.front();
+ pending_start_notify_calls_.pop();
+ scoped_ptr<device::BluetoothGattNotifySession> notify_session(
+ new BluetoothGattNotifySessionAndroid(instance_id_));
+ callbacks.first.Run(std::move(notify_session));
+ }
+}
+
+void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError(
+ BluetoothGattService::GattErrorCode error) {
+ while (!pending_start_notify_calls_.empty()) {
+ PendingStartNotifyCall callbacks = pending_start_notify_calls_.front();
+ pending_start_notify_calls_.pop();
+ callbacks.second.Run(error);
+ }
+}
+
void BluetoothRemoteGattCharacteristicAndroid::OnRead(
JNIEnv* env,
const JavaParamRef<jobject>& jcaller,

Powered by Google App Engine
This is Rietveld 408576698