| 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,
|
|
|