| Index: device/bluetooth/bluetooth_task_manager_win.cc
|
| diff --git a/device/bluetooth/bluetooth_task_manager_win.cc b/device/bluetooth/bluetooth_task_manager_win.cc
|
| index bcb3823e094a32b7ac84faaa29288fb74af275d2..1dbafc8fa93e837e8c5ab9b9af3d41476064c0d7 100644
|
| --- a/device/bluetooth/bluetooth_task_manager_win.cc
|
| +++ b/device/bluetooth/bluetooth_task_manager_win.cc
|
| @@ -122,6 +122,50 @@ void GetDeviceState(const BLUETOOTH_DEVICE_INFO& device_info,
|
| state->authenticated = !!device_info.fAuthenticated;
|
| }
|
|
|
| +typedef std::pair<
|
| + BLUETOOTH_GATT_EVENT_HANDLE,
|
| + device::BluetoothTaskManagerWin::GattCharacteristicValueChangedCallback>
|
| + CharacteristicValueChangedRegistration;
|
| +
|
| +// The key of CharacteristicValueChangedRegistrationMap is a
|
| +// GattCharacteristicValueChangedCallback pointer (cast to PVOID) to make it
|
| +// unique for different callbacks.
|
| +typedef std::unordered_map<PVOID, CharacteristicValueChangedRegistration>
|
| + CharacteristicValueChangedRegistrationMap;
|
| +
|
| +CharacteristicValueChangedRegistrationMap
|
| + characteristic_value_changed_registrations;
|
| +base::Lock characteristic_value_changed_registrations_lock;
|
| +
|
| +// Function to be registered to OS to monitor Bluetooth LE GATT event.
|
| +void OnGetGattEventWin(BTH_LE_GATT_EVENT_TYPE type,
|
| + PVOID event_parameter,
|
| + PVOID context) {
|
| + if (type != CharacteristicValueChangedEvent) {
|
| + // Right now, only characteristic value changed event is supported.
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + BLUETOOTH_GATT_VALUE_CHANGED_EVENT* event =
|
| + (BLUETOOTH_GATT_VALUE_CHANGED_EVENT*)event_parameter;
|
| + PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value_win = event->CharacteristicValue;
|
| + scoped_ptr<std::vector<uint8_t>> new_value(
|
| + new std::vector<uint8_t>(new_value_win->DataSize));
|
| + for (ULONG i = 0; i < new_value_win->DataSize; i++)
|
| + (*new_value)[i] = new_value_win->Data[i];
|
| +
|
| + // Lock shared data structure since this callback is invoked in
|
| + // BluetoothApis.dll thread.
|
| + base::AutoLock auto_lock(characteristic_value_changed_registrations_lock);
|
| + CharacteristicValueChangedRegistrationMap::const_iterator it =
|
| + characteristic_value_changed_registrations.find(context);
|
| + if (it == characteristic_value_changed_registrations.end())
|
| + return;
|
| +
|
| + it->second.second.Run(std::move(new_value));
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace device {
|
| @@ -844,6 +888,45 @@ void BluetoothTaskManagerWin::WriteGattCharacteristicValue(
|
| ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, hr));
|
| }
|
|
|
| +void BluetoothTaskManagerWin::RegisterGattCharacteristicValueChangedEvent(
|
| + base::FilePath service_path,
|
| + BTH_LE_GATT_CHARACTERISTIC characteristic,
|
| + const GattEventRegistrationCallback& callback,
|
| + const GattCharacteristicValueChangedCallback& registered_callback) {
|
| + BLUETOOTH_GATT_EVENT_HANDLE win_event_handle = NULL;
|
| +
|
| + BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION win_event_parameter;
|
| + memcpy(&(win_event_parameter.Characteristics[0]), &characteristic,
|
| + sizeof(BTH_LE_GATT_CHARACTERISTIC));
|
| + win_event_parameter.NumCharacteristics = 1;
|
| + PVOID user_event_handle = (PVOID)®istered_callback;
|
| + HRESULT hr =
|
| + win::BluetoothLowEnergyWrapper::GetInstance()->RegisterGattEvents(
|
| + service_path, CharacteristicValueChangedEvent, &win_event_parameter,
|
| + &OnGetGattEventWin, user_event_handle, &win_event_handle);
|
| + if (SUCCEEDED(hr)) {
|
| + characteristic_value_changed_registrations[user_event_handle] =
|
| + std::make_pair(win_event_handle, registered_callback);
|
| + }
|
| +
|
| + ui_task_runner_->PostTask(FROM_HERE,
|
| + base::Bind(callback, user_event_handle, hr));
|
| +}
|
| +
|
| +void BluetoothTaskManagerWin::UnregisterGattCharacteristicValueChangedEvent(
|
| + PVOID event_handle) {
|
| + DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread());
|
| +
|
| + base::AutoLock auto_lock(characteristic_value_changed_registrations_lock);
|
| + CharacteristicValueChangedRegistrationMap::const_iterator it =
|
| + characteristic_value_changed_registrations.find(event_handle);
|
| + if (it != characteristic_value_changed_registrations.end()) {
|
| + win::BluetoothLowEnergyWrapper::GetInstance()->UnregisterGattEvent(
|
| + it->second.first);
|
| + characteristic_value_changed_registrations.erase(event_handle);
|
| + }
|
| +}
|
| +
|
| void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics(
|
| const base::FilePath& service_path,
|
| const BluetoothUUID& uuid,
|
| @@ -876,8 +959,6 @@ void BluetoothTaskManagerWin::PostReadGattCharacteristicValue(
|
| FROM_HERE,
|
| base::Bind(&BluetoothTaskManagerWin::ReadGattCharacteristicValue, this,
|
| service_path, *characteristic, callback));
|
| - FOR_EACH_OBSERVER(BluetoothTaskManagerWin::Observer, observers_,
|
| - OnAttemptReadGattCharacteristic());
|
| }
|
|
|
| void BluetoothTaskManagerWin::PostWriteGattCharacteristicValue(
|
| @@ -890,8 +971,28 @@ void BluetoothTaskManagerWin::PostWriteGattCharacteristicValue(
|
| FROM_HERE,
|
| base::Bind(&BluetoothTaskManagerWin::WriteGattCharacteristicValue, this,
|
| service_path, *characteristic, new_value, callback));
|
| - FOR_EACH_OBSERVER(BluetoothTaskManagerWin::Observer, observers_,
|
| - OnAttemptWriteGattCharacteristic());
|
| +}
|
| +
|
| +void BluetoothTaskManagerWin::PostRegisterGattCharacteristicValueChangedEvent(
|
| + const base::FilePath& service_path,
|
| + const PBTH_LE_GATT_CHARACTERISTIC characteristic,
|
| + const GattEventRegistrationCallback& callback,
|
| + const GattCharacteristicValueChangedCallback& registered_callback) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| + bluetooth_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &BluetoothTaskManagerWin::RegisterGattCharacteristicValueChangedEvent,
|
| + this, service_path, *characteristic, callback, registered_callback));
|
| +}
|
| +
|
| +void BluetoothTaskManagerWin::PostUnregisterGattCharacteristicValueChangedEvent(
|
| + PVOID event_handle) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| + bluetooth_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&BluetoothTaskManagerWin::
|
| + UnregisterGattCharacteristicValueChangedEvent,
|
| + this, event_handle));
|
| }
|
|
|
| } // namespace device
|
|
|