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 0e8cfd8d845fc67a3f063834938832e018522dea..fd93ccc8e3321a26f33161ff17b62cbed6b0b2fc 100644 |
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc |
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc |
@@ -15,6 +15,7 @@ |
#include "base/single_thread_task_runner.h" |
#include "base/threading/thread_task_runner_handle.h" |
#include "device/bluetooth/bluetooth_adapter_android.h" |
+#include "device/bluetooth/bluetooth_gatt_notify_session_android.h" |
#include "device/bluetooth/bluetooth_remote_gatt_descriptor_android.h" |
#include "device/bluetooth/bluetooth_remote_gatt_service_android.h" |
#include "jni/ChromeBluetoothRemoteGattCharacteristic_jni.h" |
@@ -52,6 +53,11 @@ |
~BluetoothRemoteGattCharacteristicAndroid() { |
Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacteristicAndroidDestruction( |
AttachCurrentThread(), j_characteristic_); |
+ |
+ if (pending_start_notify_calls_.size()) { |
+ OnStartNotifySessionError( |
+ device::BluetoothRemoteGattService::GATT_ERROR_FAILED); |
+ } |
} |
// static |
@@ -95,6 +101,11 @@ |
BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const { |
NOTIMPLEMENTED(); |
return 0; |
+} |
+ |
+bool BluetoothRemoteGattCharacteristicAndroid::IsNotifying() const { |
+ NOTIMPLEMENTED(); |
+ return false; |
} |
std::vector<BluetoothRemoteGattDescriptor*> |
@@ -116,6 +127,68 @@ |
return iter->second; |
} |
+void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession( |
+ const NotifySessionCallback& callback, |
+ const ErrorCallback& error_callback) { |
+ if (!pending_start_notify_calls_.empty()) { |
+ pending_start_notify_calls_.push_back( |
+ 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::ThreadTaskRunnerHandle::Get()->PostTask( |
+ FROM_HERE, |
+ base::Bind(error_callback, |
+ BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
+ return; |
+ } |
+ |
+ std::vector<BluetoothRemoteGattDescriptor*> ccc_descriptor = |
+ GetDescriptorsByUUID(BluetoothRemoteGattDescriptor:: |
+ ClientCharacteristicConfigurationUuid()); |
+ |
+ if (ccc_descriptor.size() != 1u) { |
+ LOG(ERROR) << "Found " << ccc_descriptor.size() |
+ << " client characteristic configuration descriptors."; |
+ base::ThreadTaskRunnerHandle::Get()->PostTask( |
+ FROM_HERE, |
+ base::Bind(error_callback, |
+ (ccc_descriptor.size() == 0) |
+ ? BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED |
+ : BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
+ return; |
+ } |
+ |
+ if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotification( |
+ AttachCurrentThread(), j_characteristic_, true)) { |
+ LOG(ERROR) << "Error enabling characteristic notification"; |
+ base::ThreadTaskRunnerHandle::Get()->PostTask( |
+ FROM_HERE, base::Bind(error_callback, |
+ BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
+ return; |
+ } |
+ |
+ std::vector<uint8_t> value(2); |
+ value[0] = hasNotify ? 1 : 2; |
+ |
+ pending_start_notify_calls_.push_back( |
+ std::make_pair(callback, error_callback)); |
+ ccc_descriptor[0]->WriteRemoteDescriptor( |
+ value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: |
+ OnStartNotifySessionSuccess, |
+ base::Unretained(this)), |
+ base::Bind( |
+ &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, |
+ base::Unretained(this))); |
+} |
+ |
void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( |
const ValueCallback& callback, |
const ErrorCallback& error_callback) { |
@@ -173,6 +246,27 @@ |
const JavaParamRef<jbyteArray>& value) { |
base::android::JavaByteArrayToByteVector(env, value, &value_); |
adapter_->NotifyGattCharacteristicValueChanged(this, value_); |
+} |
+ |
+void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { |
+ std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
+ reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
+ |
+ for (const auto& callback_pair : reentrant_safe_callbacks) { |
+ std::unique_ptr<device::BluetoothGattNotifySession> notify_session( |
+ new BluetoothGattNotifySessionAndroid(instance_id_)); |
+ callback_pair.first.Run(std::move(notify_session)); |
+ } |
+} |
+ |
+void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( |
+ BluetoothRemoteGattService::GattErrorCode error) { |
+ std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
+ reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
+ |
+ for (auto const& callback_pair : reentrant_safe_callbacks) { |
+ callback_pair.second.Run(error); |
+ } |
} |
void BluetoothRemoteGattCharacteristicAndroid::OnRead( |
@@ -240,46 +334,6 @@ |
chrome_bluetooth_device)); |
} |
-void BluetoothRemoteGattCharacteristicAndroid::SubscribeToNotifications( |
- BluetoothRemoteGattDescriptor* ccc_descriptor, |
- const base::Closure& callback, |
- const ErrorCallback& error_callback) { |
- if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotification( |
- AttachCurrentThread(), j_characteristic_.obj(), true)) { |
- LOG(ERROR) << "Error enabling characteristic notification"; |
- base::ThreadTaskRunnerHandle::Get()->PostTask( |
- FROM_HERE, base::Bind(error_callback, |
- BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
- return; |
- } |
- |
- bool hasNotify = GetProperties() & PROPERTY_NOTIFY; |
- std::vector<uint8_t> value(2); |
- value[0] = hasNotify ? 1 : 2; |
- |
- ccc_descriptor->WriteRemoteDescriptor(value, callback, error_callback); |
-} |
- |
-void BluetoothRemoteGattCharacteristicAndroid::UnsubscribeFromNotifications( |
- BluetoothRemoteGattDescriptor* ccc_descriptor, |
- const base::Closure& callback, |
- const ErrorCallback& error_callback) { |
- if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotification( |
- AttachCurrentThread(), j_characteristic_.obj(), false)) { |
- LOG(ERROR) << "Error disabling characteristic notification"; |
- base::ThreadTaskRunnerHandle::Get()->PostTask( |
- FROM_HERE, |
- base::Bind(error_callback, |
- device::BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
- return; |
- } |
- |
- std::vector<uint8_t> value(2); |
- value[0] = 0; |
- |
- ccc_descriptor->WriteRemoteDescriptor(value, callback, error_callback); |
-} |
- |
BluetoothRemoteGattCharacteristicAndroid:: |
BluetoothRemoteGattCharacteristicAndroid( |
BluetoothAdapterAndroid* adapter, |