 Chromium Code Reviews
 Chromium Code Reviews Issue 2637343002:
  Implement WebBluetooth descriptor.readValue()  (Closed)
    
  
    Issue 2637343002:
  Implement WebBluetooth descriptor.readValue()  (Closed) 
  | Index: content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc | 
| diff --git a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc | 
| index 4fa8f0753137621b6e850a20bd1e24aae870503c..3305a66169cf93b5132cd89c5d57e56aa60c39c3 100644 | 
| --- a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc | 
| +++ b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc | 
| @@ -97,6 +97,8 @@ const char kClientConfigUUID[] = "2902"; | 
| // Blocklisted descriptor | 
| const char kBlocklistedDescriptorUUID[] = | 
| "bad2ddcf-60db-45cd-bef9-fd72b153cf7c"; | 
| +const char kCharacteristicUserDescription[] = | 
| + "gatt.characteristic_user_description"; | 
| // Invokes Run() on the k-th argument of the function with no arguments. | 
| ACTION_TEMPLATE(RunCallback, | 
| @@ -160,7 +162,7 @@ void NotifyDeviceChanged(MockBluetoothAdapter* adapter, | 
| observer.DeviceChanged(adapter, device); | 
| } | 
| -void PerformReadValue( | 
| +void PerformCharacteristicReadValue( | 
| MockBluetoothAdapter* adapter, | 
| MockBluetoothGattCharacteristic* characteristic, | 
| const BluetoothRemoteGattCharacteristic::ValueCallback& callback, | 
| @@ -171,6 +173,17 @@ void PerformReadValue( | 
| callback.Run(value); | 
| } | 
| +void PerformDescriptorReadValue( | 
| + MockBluetoothAdapter* adapter, | 
| + MockBluetoothGattDescriptor* descriptor, | 
| + const BluetoothRemoteGattDescriptor::ValueCallback& callback, | 
| + const std::vector<uint8_t>& value) { | 
| + for (auto& observer : adapter->GetObservers()) { | 
| + observer.GattDescriptorValueChanged(adapter, descriptor, value); | 
| + } | 
| + callback.Run(value); | 
| +} | 
| + | 
| } // namespace | 
| namespace content { | 
| @@ -216,7 +229,10 @@ LayoutTestBluetoothAdapterProvider::GetBluetoothAdapter( | 
| if (fake_adapter_name == "DisconnectingHeartRateAdapter") | 
| return GetDisconnectingHeartRateAdapter(); | 
| if (fake_adapter_name == "DisconnectingHealthThermometerAdapter") | 
| - return GetDisconnectingHealthThermometer(); | 
| + return GetDisconnectingHealthThermometer(true); | 
| + if (fake_adapter_name == | 
| + "MissingDescriptorsDisconnectingHealthThermometerAdapter") | 
| + return GetDisconnectingHealthThermometer(false); | 
| if (fake_adapter_name == "DisconnectingDuringServiceRetrievalAdapter") | 
| return GetServicesDiscoveredAfterReconnectionAdapter(true /* disconnect */); | 
| if (fake_adapter_name == "ServicesDiscoveredAfterReconnectionAdapter") | 
| @@ -679,7 +695,8 @@ LayoutTestBluetoothAdapterProvider::GetHeartRateAdapter() { | 
| // static | 
| scoped_refptr<NiceMockBluetoothAdapter> | 
| -LayoutTestBluetoothAdapterProvider::GetDisconnectingHealthThermometer() { | 
| +LayoutTestBluetoothAdapterProvider::GetDisconnectingHealthThermometer( | 
| + bool addDescriptors) { | 
| scoped_refptr<NiceMockBluetoothAdapter> adapter(GetEmptyAdapter()); | 
| NiceMockBluetoothAdapter* adapter_ptr = adapter.get(); | 
| @@ -724,30 +741,41 @@ LayoutTestBluetoothAdapterProvider::GetDisconnectingHealthThermometer() { | 
| return GetBaseGATTNotifySession(measurement_ptr->GetWeakPtr()); | 
| })); | 
| - auto user_description = base::MakeUnique<NiceMockBluetoothGattDescriptor>( | 
| - measurement_interval.get(), "gatt.characteristic_user_description", | 
| - BluetoothUUID(kUserDescriptionUUID), false, | 
| - device::BluetoothRemoteGattCharacteristic::PROPERTY_READ); | 
| - | 
| - auto client_config = base::MakeUnique<NiceMockBluetoothGattDescriptor>( | 
| - measurement_interval.get(), "gatt.client_characteristic_configuration", | 
| - BluetoothUUID(kClientConfigUUID), false, | 
| - device::BluetoothRemoteGattCharacteristic::PROPERTY_READ | | 
| - device::BluetoothRemoteGattCharacteristic::PROPERTY_WRITE); | 
| - | 
| - // Add it here with full permission as the blocklist should prevent us from | 
| - // accessing this descriptor | 
| - auto blocklisted_descriptor = | 
| - base::MakeUnique<NiceMockBluetoothGattDescriptor>( | 
| - measurement_interval.get(), "bad2ddcf-60db-45cd-bef9-fd72b153cf7c", | 
| - BluetoothUUID(kBlocklistedDescriptorUUID), false, | 
| - device::BluetoothRemoteGattCharacteristic::PROPERTY_READ | | 
| - device::BluetoothRemoteGattCharacteristic::PROPERTY_WRITE); | 
| - | 
| - measurement_interval->AddMockDescriptor(std::move(user_description)); | 
| - measurement_interval->AddMockDescriptor(std::move(client_config)); | 
| - measurement_interval->AddMockDescriptor(std::move(blocklisted_descriptor)); | 
| - | 
| + if (addDescriptors == true) { | 
| 
ortuno
2017/01/22 22:04:04
nit: no need for == true.
 
dougt
2017/01/23 21:40:35
Done.
 | 
| + std::string descriptorName = kCharacteristicUserDescription; | 
| 
ortuno
2017/01/22 22:04:04
nit: const std::string.
 
dougt
2017/01/23 21:40:35
Done.
 | 
| + auto user_description = base::MakeUnique<NiceMockBluetoothGattDescriptor>( | 
| + measurement_interval.get(), descriptorName, | 
| + BluetoothUUID(kUserDescriptionUUID), false, | 
| 
ortuno
2017/01/22 22:04:04
nit: false /* is_local */
 
dougt
2017/01/23 21:40:35
Done.
 | 
| + device::BluetoothRemoteGattCharacteristic::PROPERTY_READ); | 
| + | 
| + ON_CALL(*user_description, ReadRemoteDescriptor(_, _)) | 
| + .WillByDefault(Invoke([descriptorName]( | 
| + const BluetoothRemoteGattDescriptor::ValueCallback& callback, | 
| + const BluetoothRemoteGattDescriptor::ErrorCallback&) { | 
| + std::vector<uint8_t> value(descriptorName.begin(), | 
| 
ortuno
2017/01/22 22:04:04
optional: I think you would end up with less code
 
dougt
2017/01/23 21:40:35
Acknowledged.
 | 
| + descriptorName.end()); | 
| + callback.Run(value); | 
| + })); | 
| + | 
| + auto client_config = base::MakeUnique<NiceMockBluetoothGattDescriptor>( | 
| + measurement_interval.get(), "gatt.client_characteristic_configuration", | 
| + BluetoothUUID(kClientConfigUUID), false, | 
| 
ortuno
2017/01/22 22:04:04
nit: false /* is_local */
 
dougt
2017/01/23 21:40:35
Done.
 | 
| + device::BluetoothRemoteGattCharacteristic::PROPERTY_READ | | 
| + device::BluetoothRemoteGattCharacteristic::PROPERTY_WRITE); | 
| + | 
| + // Add it here with full permission as the blocklist should prevent us from | 
| + // accessing this descriptor | 
| + auto blocklisted_descriptor = | 
| + base::MakeUnique<NiceMockBluetoothGattDescriptor>( | 
| + measurement_interval.get(), "bad2ddcf-60db-45cd-bef9-fd72b153cf7c", | 
| + BluetoothUUID(kBlocklistedDescriptorUUID), false, | 
| + device::BluetoothRemoteGattCharacteristic::PROPERTY_READ | | 
| + device::BluetoothRemoteGattCharacteristic::PROPERTY_WRITE); | 
| + | 
| 
ortuno
2017/01/22 22:04:04
optional: What do you think about adding a ON_CALL
 
dougt
2017/01/23 21:40:35
I'll add a separate descriptor for blocklist testi
 | 
| + measurement_interval->AddMockDescriptor(std::move(user_description)); | 
| + measurement_interval->AddMockDescriptor(std::move(client_config)); | 
| + measurement_interval->AddMockDescriptor(std::move(blocklisted_descriptor)); | 
| + } | 
| health_thermometer->AddMockCharacteristic(std::move(measurement_interval)); | 
| device->AddMockService(std::move(health_thermometer)); | 
| @@ -987,9 +1015,9 @@ scoped_refptr<NiceMockBluetoothAdapter> LayoutTestBluetoothAdapterProvider:: | 
| error_callback) { | 
| base::Closure pending; | 
| if (succeeds) { | 
| - pending = | 
| - base::Bind(&PerformReadValue, base::RetainedRef(adapter_ptr), | 
| - measurement_ptr, callback, std::vector<uint8_t>({1})); | 
| + pending = base::Bind(&PerformCharacteristicReadValue, | 
| + base::RetainedRef(adapter_ptr), measurement_ptr, | 
| + callback, std::vector<uint8_t>({1})); | 
| } else { | 
| pending = base::Bind(error_callback, | 
| BluetoothRemoteGattService::GATT_ERROR_FAILED); | 
| @@ -1051,6 +1079,38 @@ scoped_refptr<NiceMockBluetoothAdapter> LayoutTestBluetoothAdapterProvider:: | 
| } | 
| })); | 
| + auto user_descriptor = base::MakeUnique<NiceMockBluetoothGattDescriptor>( | 
| + measurement_interval.get(), kCharacteristicUserDescription, | 
| + BluetoothUUID(kUserDescriptionUUID), false, | 
| + device::BluetoothRemoteGattCharacteristic::PROPERTY_READ); | 
| + | 
| + NiceMockBluetoothGattDescriptor* user_descriptor_ptr = user_descriptor.get(); | 
| + ON_CALL(*user_descriptor, ReadRemoteDescriptor(_, _)) | 
| + .WillByDefault(Invoke([adapter_ptr, device_ptr, user_descriptor_ptr, | 
| + disconnect, succeeds]( | 
| + const BluetoothRemoteGattDescriptor::ValueCallback& callback, | 
| + const BluetoothRemoteGattDescriptor::ErrorCallback& error_callback) { | 
| + base::Closure pending; | 
| + if (succeeds) { | 
| + pending = base::Bind( | 
| + &PerformDescriptorReadValue, base::RetainedRef(adapter_ptr), | 
| + user_descriptor_ptr, callback, std::vector<uint8_t>({1})); | 
| + } else { | 
| + pending = base::Bind(error_callback, | 
| + BluetoothRemoteGattService::GATT_ERROR_FAILED); | 
| + } | 
| + device_ptr->PushPendingCallback(pending); | 
| + if (disconnect) { | 
| + device_ptr->SetConnected(false); | 
| + base::ThreadTaskRunnerHandle::Get()->PostTask( | 
| + FROM_HERE, | 
| + base::Bind(&NotifyDeviceChanged, base::RetainedRef(adapter_ptr), | 
| + device_ptr)); | 
| + } | 
| + })); | 
| + | 
| + measurement_interval->AddMockDescriptor(std::move(user_descriptor)); | 
| + | 
| health_thermometer->AddMockCharacteristic(std::move(measurement_interval)); | 
| device->AddMockService(std::move(health_thermometer)); | 
| adapter->AddMockDevice(std::move(device)); | 
| @@ -1639,6 +1699,17 @@ LayoutTestBluetoothAdapterProvider::GetErrorCharacteristic( | 
| ON_CALL(*characteristic, StartNotifySession(_, _)) | 
| .WillByDefault(RunCallback<1 /* error_callback */>(error_code)); | 
| + // Add error descriptor to |characteristic| | 
| + auto error_descriptor = base::MakeUnique<NiceMockBluetoothGattDescriptor>( | 
| + characteristic.get(), kCharacteristicUserDescription, | 
| + BluetoothUUID(kUserDescriptionUUID), false, | 
| + device::BluetoothRemoteGattCharacteristic::PROPERTY_READ); | 
| + | 
| + ON_CALL(*error_descriptor, ReadRemoteDescriptor(_, _)) | 
| + .WillByDefault(RunCallback<1 /* error_callback */>(error_code)); | 
| + | 
| + characteristic->AddMockDescriptor(std::move(error_descriptor)); | 
| + | 
| return characteristic; | 
| } | 
| @@ -1719,4 +1790,4 @@ std::string LayoutTestBluetoothAdapterProvider::makeMACAddress(uint64_t addr) { | 
| base::StringPrintf("%012" PRIx64, addr)); | 
| } | 
| -} // namespace content | 
| +} // namespace content |