0

bluetooth: Remove implicit value copying during Mojo IPC

Update the Web Bluetooth Mojo interface to use the ReadOnlyBuffer type
so that the generated C++ bindings use base::span, which doesn't require
copying the GATT characteristic or descriptor value out of the Mojo
message just so that it can be put into an std::vector.

Right now in the write case the value still needs to be copied into a
std::vector in order to call into //device/bluetooth. Updating this
interface to use base::span can be done in a follow-up patch to remove
the now explicit std::vector constructor invocations.

Change-Id: I1f21e97ebf28ea38ddb49bed9e7500ee04809968
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5954717
Auto-Submit: Reilly Grant <reillyg@chromium.org>
Reviewed-by: Jack Hsieh <chengweih@chromium.org>
Reviewed-by: Matthew Denton <mpdenton@chromium.org>
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1372994}
This commit is contained in:
Reilly Grant
2024-10-23 22:40:31 +00:00
committed by Chromium LUCI CQ
parent 11e05a6e26
commit 8002d42fd5
16 changed files with 113 additions and 121 deletions

@@ -7,6 +7,7 @@
#include <string> #include <string>
#include "base/containers/span.h"
#include "base/functional/callback_forward.h" #include "base/functional/callback_forward.h"
#include "content/public/browser/bluetooth_delegate.h" #include "content/public/browser/bluetooth_delegate.h"
#include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_device.h"
@@ -72,7 +73,7 @@ class WebBluetoothPairingManagerDelegate {
// error. // error.
virtual void RemoteCharacteristicWriteValue( virtual void RemoteCharacteristicWriteValue(
const std::string& characteristic_instance_id, const std::string& characteristic_instance_id,
const std::vector<uint8_t>& value, base::span<const uint8_t> value,
blink::mojom::WebBluetoothWriteType write_type, blink::mojom::WebBluetoothWriteType write_type,
blink::mojom::WebBluetoothService::RemoteCharacteristicWriteValueCallback blink::mojom::WebBluetoothService::RemoteCharacteristicWriteValueCallback
callback) = 0; callback) = 0;
@@ -94,7 +95,7 @@ class WebBluetoothPairingManagerDelegate {
// error. // error.
virtual void RemoteDescriptorWriteValue( virtual void RemoteDescriptorWriteValue(
const std::string& descriptor_instance_id, const std::string& descriptor_instance_id,
const std::vector<uint8_t>& value, base::span<const uint8_t> value,
blink::mojom::WebBluetoothService::RemoteDescriptorWriteValueCallback blink::mojom::WebBluetoothService::RemoteDescriptorWriteValueCallback
callback) = 0; callback) = 0;

@@ -28,7 +28,7 @@ void OnPairForReadCharacteristicCallback(
if (error_code) { if (error_code) {
std::move(callback).Run( std::move(callback).Run(
WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(*error_code), WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(*error_code),
/*value=*/std::nullopt); /*value=*/{});
return; return;
} }
pairing_manager_delegate->RemoteCharacteristicReadValue( pairing_manager_delegate->RemoteCharacteristicReadValue(
@@ -59,7 +59,7 @@ void OnPairForReadDescriptorCallback(
if (error_code) { if (error_code) {
std::move(callback).Run( std::move(callback).Run(
WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(*error_code), WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(*error_code),
/*value=*/std::nullopt); /*value=*/{});
return; return;
} }
pairing_manager_delegate->RemoteDescriptorReadValue(descriptor_instance_id, pairing_manager_delegate->RemoteDescriptorReadValue(descriptor_instance_id,
@@ -129,7 +129,7 @@ void WebBluetoothPairingManagerImpl::PairForCharacteristicReadValue(
std::move(read_callback) std::move(read_callback)
.Run(WebBluetoothServiceImpl::TranslateConnectErrorAndRecord( .Run(WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(
BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN), BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN),
/*value=*/std::nullopt); /*value=*/{});
return; return;
} }
@@ -171,7 +171,7 @@ void WebBluetoothPairingManagerImpl::PairForDescriptorReadValue(
std::move(read_callback) std::move(read_callback)
.Run(WebBluetoothServiceImpl::TranslateConnectErrorAndRecord( .Run(WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(
BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN), BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN),
/*value=*/std::nullopt); /*value=*/{});
return; return;
} }

@@ -204,7 +204,7 @@ class BluetoothPairingManagerTest : public testing::Test,
} }
std::move(callback).Run(WebBluetoothResult::CONNECT_AUTH_REJECTED, std::move(callback).Run(WebBluetoothResult::CONNECT_AUTH_REJECTED,
std::nullopt); /*value=*/{});
} }
void RemoteDescriptorReadValue( void RemoteDescriptorReadValue(
@@ -222,12 +222,12 @@ class BluetoothPairingManagerTest : public testing::Test,
} }
std::move(callback).Run(WebBluetoothResult::CONNECT_AUTH_REJECTED, std::move(callback).Run(WebBluetoothResult::CONNECT_AUTH_REJECTED,
std::nullopt); /*value=*/{});
} }
void RemoteCharacteristicWriteValue( void RemoteCharacteristicWriteValue(
const std::string& characteristic_instance_id, const std::string& characteristic_instance_id,
const std::vector<uint8_t>& value, base::span<const uint8_t> value,
WebBluetoothWriteType write_type, WebBluetoothWriteType write_type,
WebBluetoothService::RemoteCharacteristicWriteValueCallback callback) WebBluetoothService::RemoteCharacteristicWriteValueCallback callback)
override { override {
@@ -237,7 +237,7 @@ class BluetoothPairingManagerTest : public testing::Test,
return; return;
} }
if (device_paired_) { if (device_paired_) {
characteristic_value_ = value; characteristic_value_ = std::vector<uint8_t>(value.begin(), value.end());
std::move(callback).Run(WebBluetoothResult::SUCCESS); std::move(callback).Run(WebBluetoothResult::SUCCESS);
return; return;
} }
@@ -247,7 +247,7 @@ class BluetoothPairingManagerTest : public testing::Test,
void RemoteDescriptorWriteValue( void RemoteDescriptorWriteValue(
const std::string& descriptor_instance_id, const std::string& descriptor_instance_id,
const std::vector<uint8_t>& value, base::span<const uint8_t> value,
WebBluetoothService::RemoteDescriptorWriteValueCallback callback) WebBluetoothService::RemoteDescriptorWriteValueCallback callback)
override { override {
if (descriptor_instance_id != kValidTestData.descriptor_instance_id) { if (descriptor_instance_id != kValidTestData.descriptor_instance_id) {
@@ -255,7 +255,7 @@ class BluetoothPairingManagerTest : public testing::Test,
return; return;
} }
if (device_paired_) { if (device_paired_) {
descriptor_value_ = value; descriptor_value_ = std::vector<uint8_t>(value.begin(), value.end());
std::move(callback).Run(WebBluetoothResult::SUCCESS); std::move(callback).Run(WebBluetoothResult::SUCCESS);
return; return;
} }
@@ -336,9 +336,8 @@ TEST_F(BluetoothPairingManagerTest, ReadSuccessfulAuthFirstSuccess) {
pairing_manager()->PairForCharacteristicReadValue( pairing_manager()->PairForCharacteristicReadValue(
kValidTestData.characteristic_instance_id, kValidTestData.characteristic_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop, &expected_value]( [&loop, &expected_value](WebBluetoothResult result,
WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::SUCCESS, result); EXPECT_EQ(WebBluetoothResult::SUCCESS, result);
EXPECT_EQ(value, expected_value) EXPECT_EQ(value, expected_value)
<< "Incorrect characteristic value"; << "Incorrect characteristic value";
@@ -357,9 +356,8 @@ TEST_F(BluetoothPairingManagerTest, ReadSuccessfulAuthSecondSuccess) {
pairing_manager()->PairForCharacteristicReadValue( pairing_manager()->PairForCharacteristicReadValue(
kValidTestData.characteristic_instance_id, kValidTestData.characteristic_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop, &expected_value]( [&loop, &expected_value](WebBluetoothResult result,
WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::SUCCESS, result); EXPECT_EQ(WebBluetoothResult::SUCCESS, result);
EXPECT_EQ(value, expected_value) EXPECT_EQ(value, expected_value)
<< "Incorrect characteristic value"; << "Incorrect characteristic value";
@@ -377,10 +375,9 @@ TEST_F(BluetoothPairingManagerTest, ReadFailAllAuthsFail) {
pairing_manager()->PairForCharacteristicReadValue( pairing_manager()->PairForCharacteristicReadValue(
kValidTestData.characteristic_instance_id, kValidTestData.characteristic_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop](WebBluetoothResult result, [&loop](WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_REJECTED, result); EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_REJECTED, result);
EXPECT_FALSE(value.has_value()); EXPECT_TRUE(value.empty());
loop.Quit(); loop.Quit();
})); }));
@@ -396,10 +393,9 @@ TEST_F(BluetoothPairingManagerTest, ReadInvalidCharacteristicId) {
pairing_manager()->PairForCharacteristicReadValue( pairing_manager()->PairForCharacteristicReadValue(
kValidNonTestData.characteristic_instance_id, kValidNonTestData.characteristic_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop](WebBluetoothResult result, [&loop](WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::CONNECT_UNKNOWN_ERROR, result); EXPECT_EQ(WebBluetoothResult::CONNECT_UNKNOWN_ERROR, result);
EXPECT_FALSE(value.has_value()); EXPECT_TRUE(value.empty());
loop.Quit(); loop.Quit();
})); }));
@@ -414,10 +410,9 @@ TEST_F(BluetoothPairingManagerTest, ReadCharacteristicDeleteDelegate) {
pairing_manager()->PairForCharacteristicReadValue( pairing_manager()->PairForCharacteristicReadValue(
kValidTestData.characteristic_instance_id, kValidTestData.characteristic_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop](WebBluetoothResult result, [&loop](WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_CANCELED, result); EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_CANCELED, result);
EXPECT_FALSE(value.has_value()); EXPECT_TRUE(value.empty());
loop.Quit(); loop.Quit();
})); }));
@@ -438,8 +433,7 @@ TEST_F(BluetoothPairingManagerTest, ReadCharacteristicDoublePair) {
kValidTestData.characteristic_instance_id, kValidTestData.characteristic_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop, &callback_count, &expected_value]( [&loop, &callback_count, &expected_value](
WebBluetoothResult result, WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::SUCCESS, result); EXPECT_EQ(WebBluetoothResult::SUCCESS, result);
EXPECT_EQ(value, expected_value); EXPECT_EQ(value, expected_value);
if (++callback_count == 2) if (++callback_count == 2)
@@ -451,9 +445,8 @@ TEST_F(BluetoothPairingManagerTest, ReadCharacteristicDoublePair) {
pairing_manager()->PairForCharacteristicReadValue( pairing_manager()->PairForCharacteristicReadValue(
kValidTestData.characteristic_instance_id, kValidTestData.characteristic_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop, &callback_count]( [&loop, &callback_count](WebBluetoothResult result,
WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_CANCELED, result); EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_CANCELED, result);
if (++callback_count == 2) if (++callback_count == 2)
loop.Quit(); loop.Quit();
@@ -616,9 +609,8 @@ TEST_F(BluetoothPairingManagerTest, DescriptorReadSuccessfulAuthFirstSuccess) {
pairing_manager()->PairForDescriptorReadValue( pairing_manager()->PairForDescriptorReadValue(
kValidTestData.descriptor_instance_id, kValidTestData.descriptor_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop, &expected_value]( [&loop, &expected_value](WebBluetoothResult result,
WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::SUCCESS, result); EXPECT_EQ(WebBluetoothResult::SUCCESS, result);
EXPECT_EQ(value, expected_value) << "Incorrect descriptor value"; EXPECT_EQ(value, expected_value) << "Incorrect descriptor value";
loop.Quit(); loop.Quit();
@@ -636,9 +628,8 @@ TEST_F(BluetoothPairingManagerTest, DescriptorReadSuccessfulAuthSecondSuccess) {
pairing_manager()->PairForDescriptorReadValue( pairing_manager()->PairForDescriptorReadValue(
kValidTestData.descriptor_instance_id, kValidTestData.descriptor_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop, &expected_value]( [&loop, &expected_value](WebBluetoothResult result,
WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::SUCCESS, result); EXPECT_EQ(WebBluetoothResult::SUCCESS, result);
EXPECT_EQ(value, expected_value) << "Incorrect descriptor value"; EXPECT_EQ(value, expected_value) << "Incorrect descriptor value";
loop.Quit(); loop.Quit();
@@ -655,10 +646,9 @@ TEST_F(BluetoothPairingManagerTest, DescriptorReadFailAllAuthsFail) {
pairing_manager()->PairForDescriptorReadValue( pairing_manager()->PairForDescriptorReadValue(
kValidTestData.descriptor_instance_id, kValidTestData.descriptor_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop](WebBluetoothResult result, [&loop](WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_REJECTED, result); EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_REJECTED, result);
EXPECT_FALSE(value.has_value()); EXPECT_TRUE(value.empty());
loop.Quit(); loop.Quit();
})); }));
@@ -674,8 +664,7 @@ TEST_F(BluetoothPairingManagerTest, DescriptorReadInvalidDescriptorId) {
pairing_manager()->PairForDescriptorReadValue( pairing_manager()->PairForDescriptorReadValue(
kValidNonTestData.descriptor_instance_id, kValidNonTestData.descriptor_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop](WebBluetoothResult result, [&loop](WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::CONNECT_UNKNOWN_ERROR, result); EXPECT_EQ(WebBluetoothResult::CONNECT_UNKNOWN_ERROR, result);
loop.Quit(); loop.Quit();
})); }));
@@ -691,8 +680,7 @@ TEST_F(BluetoothPairingManagerTest, ReadDescriptorDeleteDelegate) {
pairing_manager()->PairForDescriptorReadValue( pairing_manager()->PairForDescriptorReadValue(
kValidTestData.descriptor_instance_id, kValidTestData.descriptor_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop](WebBluetoothResult result, [&loop](WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_CANCELED, result); EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_CANCELED, result);
loop.Quit(); loop.Quit();
})); }));
@@ -714,8 +702,7 @@ TEST_F(BluetoothPairingManagerTest, ReadDescriptorDoublePair) {
kValidTestData.descriptor_instance_id, kValidTestData.descriptor_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop, &callback_count, &expected_value]( [&loop, &callback_count, &expected_value](
WebBluetoothResult result, WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::SUCCESS, result); EXPECT_EQ(WebBluetoothResult::SUCCESS, result);
EXPECT_EQ(value, expected_value) << "Incorrect descriptor value"; EXPECT_EQ(value, expected_value) << "Incorrect descriptor value";
if (++callback_count == 2) if (++callback_count == 2)
@@ -727,11 +714,10 @@ TEST_F(BluetoothPairingManagerTest, ReadDescriptorDoublePair) {
pairing_manager()->PairForDescriptorReadValue( pairing_manager()->PairForDescriptorReadValue(
kValidTestData.descriptor_instance_id, kValidTestData.descriptor_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&loop, &callback_count]( [&loop, &callback_count](WebBluetoothResult result,
WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_CANCELED, result); EXPECT_EQ(WebBluetoothResult::CONNECT_AUTH_CANCELED, result);
EXPECT_FALSE(value.has_value()); EXPECT_TRUE(value.empty());
if (++callback_count == 2) if (++callback_count == 2)
loop.Quit(); loop.Quit();
})); }));

@@ -1111,7 +1111,7 @@ void WebBluetoothServiceImpl::RemoteCharacteristicReadValue(
if (query_result.outcome != CacheQueryOutcome::kSuccess) { if (query_result.outcome != CacheQueryOutcome::kSuccess) {
RecordCharacteristicReadValueOutcome(query_result.outcome); RecordCharacteristicReadValueOutcome(query_result.outcome);
std::move(callback).Run(query_result.GetWebResult(), std::move(callback).Run(query_result.GetWebResult(),
std::nullopt /* value */); /*value=*/{});
return; return;
} }
@@ -1119,7 +1119,7 @@ void WebBluetoothServiceImpl::RemoteCharacteristicReadValue(
query_result.characteristic->GetUUID())) { query_result.characteristic->GetUUID())) {
RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::kBlocklisted); RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::kBlocklisted);
std::move(callback).Run(blink::mojom::WebBluetoothResult::BLOCKLISTED_READ, std::move(callback).Run(blink::mojom::WebBluetoothResult::BLOCKLISTED_READ,
std::nullopt /* value */); /*value=*/{});
return; return;
} }
@@ -1131,7 +1131,7 @@ void WebBluetoothServiceImpl::RemoteCharacteristicReadValue(
void WebBluetoothServiceImpl::RemoteCharacteristicWriteValue( void WebBluetoothServiceImpl::RemoteCharacteristicWriteValue(
const std::string& characteristic_instance_id, const std::string& characteristic_instance_id,
const std::vector<uint8_t>& value, base::span<const uint8_t> value,
blink::mojom::WebBluetoothWriteType write_type, blink::mojom::WebBluetoothWriteType write_type,
RemoteCharacteristicWriteValueCallback callback) { RemoteCharacteristicWriteValueCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -1175,22 +1175,26 @@ void WebBluetoothServiceImpl::RemoteCharacteristicWriteValue(
BluetoothGattCharacteristic::ErrorCallback write_error_callback = BluetoothGattCharacteristic::ErrorCallback write_error_callback =
base::BindOnce(&WebBluetoothServiceImpl::OnCharacteristicWriteValueFailed, base::BindOnce(&WebBluetoothServiceImpl::OnCharacteristicWriteValueFailed,
weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id,
value, write_type, std::move(split_callback.second)); std::vector<uint8_t>(value.begin(), value.end()),
write_type, std::move(split_callback.second));
using WebBluetoothWriteType = blink::mojom::WebBluetoothWriteType; using WebBluetoothWriteType = blink::mojom::WebBluetoothWriteType;
using WriteType = BluetoothRemoteGattCharacteristic::WriteType; using WriteType = BluetoothRemoteGattCharacteristic::WriteType;
switch (write_type) { switch (write_type) {
case WebBluetoothWriteType::kWriteDefaultDeprecated: case WebBluetoothWriteType::kWriteDefaultDeprecated:
query_result.characteristic->DeprecatedWriteRemoteCharacteristic( query_result.characteristic->DeprecatedWriteRemoteCharacteristic(
value, std::move(write_callback), std::move(write_error_callback)); std::vector<uint8_t>(value.begin(), value.end()),
std::move(write_callback), std::move(write_error_callback));
break; break;
case WebBluetoothWriteType::kWriteWithResponse: case WebBluetoothWriteType::kWriteWithResponse:
query_result.characteristic->WriteRemoteCharacteristic( query_result.characteristic->WriteRemoteCharacteristic(
value, WriteType::kWithResponse, std::move(write_callback), std::vector<uint8_t>(value.begin(), value.end()),
WriteType::kWithResponse, std::move(write_callback),
std::move(write_error_callback)); std::move(write_error_callback));
break; break;
case WebBluetoothWriteType::kWriteWithoutResponse: case WebBluetoothWriteType::kWriteWithoutResponse:
query_result.characteristic->WriteRemoteCharacteristic( query_result.characteristic->WriteRemoteCharacteristic(
value, WriteType::kWithoutResponse, std::move(write_callback), std::vector<uint8_t>(value.begin(), value.end()),
WriteType::kWithoutResponse, std::move(write_callback),
std::move(write_error_callback)); std::move(write_error_callback));
break; break;
} }
@@ -1330,14 +1334,14 @@ void WebBluetoothServiceImpl::RemoteDescriptorReadValue(
if (query_result.outcome != CacheQueryOutcome::kSuccess) { if (query_result.outcome != CacheQueryOutcome::kSuccess) {
std::move(callback).Run(query_result.GetWebResult(), std::move(callback).Run(query_result.GetWebResult(),
std::nullopt /* value */); /*value=*/{});
return; return;
} }
if (BluetoothBlocklist::Get().IsExcludedFromReads( if (BluetoothBlocklist::Get().IsExcludedFromReads(
query_result.descriptor->GetUUID())) { query_result.descriptor->GetUUID())) {
std::move(callback).Run(blink::mojom::WebBluetoothResult::BLOCKLISTED_READ, std::move(callback).Run(blink::mojom::WebBluetoothResult::BLOCKLISTED_READ,
std::nullopt /* value */); /*value=*/{});
return; return;
} }
@@ -1349,7 +1353,7 @@ void WebBluetoothServiceImpl::RemoteDescriptorReadValue(
void WebBluetoothServiceImpl::RemoteDescriptorWriteValue( void WebBluetoothServiceImpl::RemoteDescriptorWriteValue(
const std::string& descriptor_instance_id, const std::string& descriptor_instance_id,
const std::vector<uint8_t>& value, base::span<const uint8_t> value,
RemoteDescriptorWriteValueCallback callback) { RemoteDescriptorWriteValueCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -1384,13 +1388,14 @@ void WebBluetoothServiceImpl::RemoteDescriptorWriteValue(
// the callee interface. // the callee interface.
auto split_callback = base::SplitOnceCallback(std::move(callback)); auto split_callback = base::SplitOnceCallback(std::move(callback));
query_result.descriptor->WriteRemoteDescriptor( query_result.descriptor->WriteRemoteDescriptor(
value, std::vector<uint8_t>(value.begin(), value.end()),
base::BindOnce(&WebBluetoothServiceImpl::OnDescriptorWriteValueSuccess, base::BindOnce(&WebBluetoothServiceImpl::OnDescriptorWriteValueSuccess,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
std::move(split_callback.first)), std::move(split_callback.first)),
base::BindOnce(&WebBluetoothServiceImpl::OnDescriptorWriteValueFailed, base::BindOnce(&WebBluetoothServiceImpl::OnDescriptorWriteValueFailed,
weak_ptr_factory_.GetWeakPtr(), descriptor_instance_id, weak_ptr_factory_.GetWeakPtr(), descriptor_instance_id,
value, std::move(split_callback.second))); std::vector<uint8_t>(value.begin(), value.end()),
std::move(split_callback.second)));
} }
void WebBluetoothServiceImpl::RequestScanningStart( void WebBluetoothServiceImpl::RequestScanningStart(
@@ -1935,7 +1940,7 @@ void WebBluetoothServiceImpl::OnCharacteristicReadValue(
std::move(callback).Run( std::move(callback).Run(
TranslateGATTErrorAndRecord(error_code.value(), TranslateGATTErrorAndRecord(error_code.value(),
UMAGATTOperation::kCharacteristicRead), UMAGATTOperation::kCharacteristicRead),
/*value=*/std::nullopt); /*value=*/{});
return; return;
} }
RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::kSuccess); RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::kSuccess);
@@ -2082,7 +2087,7 @@ void WebBluetoothServiceImpl::OnDescriptorReadValue(
std::move(callback).Run( std::move(callback).Run(
TranslateGATTErrorAndRecord(error_code.value(), TranslateGATTErrorAndRecord(error_code.value(),
UMAGATTOperation::kDescriptorReadObsolete), UMAGATTOperation::kDescriptorReadObsolete),
/*value=*/std::nullopt); /*value=*/{});
return; return;
} }
std::move(callback).Run(blink::mojom::WebBluetoothResult::SUCCESS, value); std::move(callback).Run(blink::mojom::WebBluetoothResult::SUCCESS, value);

@@ -260,7 +260,7 @@ class CONTENT_EXPORT WebBluetoothServiceImpl
RemoteCharacteristicReadValueCallback callback) override; RemoteCharacteristicReadValueCallback callback) override;
void RemoteCharacteristicWriteValue( void RemoteCharacteristicWriteValue(
const std::string& characteristic_instance_id, const std::string& characteristic_instance_id,
const std::vector<uint8_t>& value, base::span<const uint8_t> value,
blink::mojom::WebBluetoothWriteType write_type, blink::mojom::WebBluetoothWriteType write_type,
RemoteCharacteristicWriteValueCallback callback) override; RemoteCharacteristicWriteValueCallback callback) override;
void RemoteCharacteristicStartNotifications( void RemoteCharacteristicStartNotifications(
@@ -286,7 +286,7 @@ class CONTENT_EXPORT WebBluetoothServiceImpl
RemoteDescriptorReadValueCallback callback) override; RemoteDescriptorReadValueCallback callback) override;
void RemoteDescriptorWriteValue( void RemoteDescriptorWriteValue(
const std::string& descriptor_instance_id, const std::string& descriptor_instance_id,
const std::vector<uint8_t>& value, base::span<const uint8_t> value,
RemoteDescriptorWriteValueCallback callback) override; RemoteDescriptorWriteValueCallback callback) override;
void RequestScanningStart( void RequestScanningStart(
mojo::PendingAssociatedRemote< mojo::PendingAssociatedRemote<

@@ -186,7 +186,7 @@ class FakeWebBluetoothCharacteristicClient : WebBluetoothCharacteristicClient {
protected: protected:
// WebBluetoothCharacteristicClient implementation: // WebBluetoothCharacteristicClient implementation:
void RemoteCharacteristicValueChanged( void RemoteCharacteristicValueChanged(
const std::vector<uint8_t>& value) override { base::span<const uint8_t> value) override {
NOTREACHED_IN_MIGRATION(); NOTREACHED_IN_MIGRATION();
} }
@@ -933,12 +933,12 @@ TEST_F(WebBluetoothServiceImplTest,
characteristic_instance_id, characteristic_instance_id,
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&callback_called](blink::mojom::WebBluetoothResult result, [&callback_called](blink::mojom::WebBluetoothResult result,
const std::optional<std::vector<uint8_t>>& value) { base::span<const uint8_t> value) {
callback_called = true; callback_called = true;
EXPECT_EQ( EXPECT_EQ(
blink::mojom::WebBluetoothResult::GATT_OPERATION_IN_PROGRESS, blink::mojom::WebBluetoothResult::GATT_OPERATION_IN_PROGRESS,
result); result);
EXPECT_FALSE(value.has_value()); EXPECT_TRUE(value.empty());
}), }),
device::BluetoothGattService::GattErrorCode::kInProgress, device::BluetoothGattService::GattErrorCode::kInProgress,
read_error_value); read_error_value);
@@ -968,13 +968,12 @@ TEST_F(WebBluetoothServiceImplTest, ReadCharacteristicValueNotAuthorized) {
service_ptr_->OnCharacteristicReadValue( service_ptr_->OnCharacteristicReadValue(
test_characteristic.GetIdentifier(), test_characteristic.GetIdentifier(),
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&read_value_callback_called]( [&read_value_callback_called](blink::mojom::WebBluetoothResult result,
blink::mojom::WebBluetoothResult result, base::span<const uint8_t> value) {
const std::optional<std::vector<uint8_t>>& value) {
read_value_callback_called = true; read_value_callback_called = true;
EXPECT_EQ(blink::mojom::WebBluetoothResult::GATT_NOT_AUTHORIZED, EXPECT_EQ(blink::mojom::WebBluetoothResult::GATT_NOT_AUTHORIZED,
result); result);
EXPECT_FALSE(value.has_value()); EXPECT_TRUE(value.empty());
}), }),
device::BluetoothGattService::GattErrorCode::kNotAuthorized, device::BluetoothGattService::GattErrorCode::kNotAuthorized,
read_error_value); read_error_value);

@@ -1808,7 +1808,10 @@ mojom("web_bluetooth_mojo_bindings") {
sources = [ "bluetooth/web_bluetooth.mojom" ] sources = [ "bluetooth/web_bluetooth.mojom" ]
public_deps = [ "//device/bluetooth/public/mojom" ] public_deps = [
"//device/bluetooth/public/mojom",
"//mojo/public/mojom/base",
]
shared_cpp_typemaps = [ shared_cpp_typemaps = [
{ {

@@ -5,6 +5,7 @@
module blink.mojom; module blink.mojom;
import "device/bluetooth/public/mojom/uuid.mojom"; import "device/bluetooth/public/mojom/uuid.mojom";
import "mojo/public/mojom/base/read_only_buffer.mojom";
// Bluetooth Terminology: // Bluetooth Terminology:
// //
@@ -286,11 +287,11 @@ interface WebBluetoothService {
// |characteristic_instance_id|. If the value is successfully read the // |characteristic_instance_id|. If the value is successfully read the
// callback will be run with WebBluetoothResult::SUCCESS and the // callback will be run with WebBluetoothResult::SUCCESS and the
// characteristic's value. If the value is not successfully read the // characteristic's value. If the value is not successfully read the
// callback with be run with the corresponding error and nullptr for value. // callback with be run with the corresponding error and an empty value.
RemoteCharacteristicReadValue( RemoteCharacteristicReadValue(
string characteristic_instance_id) => ( string characteristic_instance_id) => (
WebBluetoothResult result, WebBluetoothResult result,
array<uint8>? value); mojo_base.mojom.ReadOnlyBuffer value);
// Writes a value to the characteristic identified by // Writes a value to the characteristic identified by
// |characteristic_instance_id|. The callback is run with // |characteristic_instance_id|. The callback is run with
@@ -298,7 +299,7 @@ interface WebBluetoothService {
// written. // written.
RemoteCharacteristicWriteValue( RemoteCharacteristicWriteValue(
string characteristic_instance_id, string characteristic_instance_id,
array<uint8> value, mojo_base.mojom.ReadOnlyBuffer value,
WebBluetoothWriteType write_type) => (WebBluetoothResult result); WebBluetoothWriteType write_type) => (WebBluetoothResult result);
// Starts notifications for the characteristic identified by // Starts notifications for the characteristic identified by
@@ -331,11 +332,11 @@ interface WebBluetoothService {
// |descriptor_instance_id|. If the value is successfully read the callback // |descriptor_instance_id|. If the value is successfully read the callback
// will be run with WebBluetoothResult::SUCCESS and the descriptor's value. If // will be run with WebBluetoothResult::SUCCESS and the descriptor's value. If
// the value is not successfully read the callback with be run with the // the value is not successfully read the callback with be run with the
// corresponding error and nullptr for value // corresponding error and an empty value.
RemoteDescriptorReadValue( RemoteDescriptorReadValue(
string descriptor_instance_id) => ( string descriptor_instance_id) => (
WebBluetoothResult result, WebBluetoothResult result,
array<uint8>? value); mojo_base.mojom.ReadOnlyBuffer value);
// Writes a value to the descriptor identified by // Writes a value to the descriptor identified by
// |descriptor_instance_id|. The callback is run with // |descriptor_instance_id|. The callback is run with
@@ -343,7 +344,7 @@ interface WebBluetoothService {
// written. // written.
RemoteDescriptorWriteValue( RemoteDescriptorWriteValue(
string descriptor_instance_id, string descriptor_instance_id,
array<uint8> value) => (WebBluetoothResult result); mojo_base.mojom.ReadOnlyBuffer value) => (WebBluetoothResult result);
// Starts scanning for low energy devices. // Starts scanning for low energy devices.
RequestScanningStart( RequestScanningStart(
@@ -371,7 +372,7 @@ interface WebBluetoothServerClient {
// events. // events.
interface WebBluetoothCharacteristicClient { interface WebBluetoothCharacteristicClient {
// Called when we receive a notification for the characteristic. // Called when we receive a notification for the characteristic.
RemoteCharacteristicValueChanged(array<uint8> value); RemoteCharacteristicValueChanged(mojo_base.mojom.ReadOnlyBuffer value);
}; };
// Classes that implement this interface will be notified of device // Classes that implement this interface will be notified of device

@@ -24,7 +24,7 @@ class BluetoothManufacturerDataMapIterationSource final
return false; return false;
map_key = iterator_->key->id; map_key = iterator_->key->id;
map_value = NotShared<DOMDataView>( map_value = NotShared<DOMDataView>(
BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(iterator_->value)); BluetoothRemoteGATTUtils::ConvertSpanToDataView(iterator_->value));
++iterator_; ++iterator_;
return true; return true;
} }
@@ -68,7 +68,7 @@ bool BluetoothManufacturerDataMap::GetMapEntry(ScriptState*,
return false; return false;
DOMDataView* dom_data_view = DOMDataView* dom_data_view =
BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(it->value); BluetoothRemoteGATTUtils::ConvertSpanToDataView(it->value);
value = NotShared<DOMDataView>(dom_data_view); value = NotShared<DOMDataView>(dom_data_view);
return true; return true;

@@ -50,10 +50,10 @@ void BluetoothRemoteGATTCharacteristic::SetValue(DOMDataView* dom_data_view) {
} }
void BluetoothRemoteGATTCharacteristic::RemoteCharacteristicValueChanged( void BluetoothRemoteGATTCharacteristic::RemoteCharacteristicValueChanged(
const Vector<uint8_t>& value) { base::span<const uint8_t> value) {
if (!GetGatt()->connected()) if (!GetGatt()->connected())
return; return;
SetValue(BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(value)); SetValue(BluetoothRemoteGATTUtils::ConvertSpanToDataView(value));
if (notification_registration_in_progress()) { if (notification_registration_in_progress()) {
// Save event and value to be dispatched after notification is registered. // Save event and value to be dispatched after notification is registered.
deferred_value_change_data_.push_back( deferred_value_change_data_.push_back(
@@ -92,7 +92,7 @@ void BluetoothRemoteGATTCharacteristic::AddedEventListener(
void BluetoothRemoteGATTCharacteristic::ReadValueCallback( void BluetoothRemoteGATTCharacteristic::ReadValueCallback(
ScriptPromiseResolver<NotShared<DOMDataView>>* resolver, ScriptPromiseResolver<NotShared<DOMDataView>>* resolver,
mojom::blink::WebBluetoothResult result, mojom::blink::WebBluetoothResult result,
const std::optional<Vector<uint8_t>>& value) { base::span<const uint8_t> value) {
if (!resolver->GetExecutionContext() || if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed()) resolver->GetExecutionContext()->IsContextDestroyed())
return; return;
@@ -105,9 +105,8 @@ void BluetoothRemoteGATTCharacteristic::ReadValueCallback(
} }
if (result == mojom::blink::WebBluetoothResult::SUCCESS) { if (result == mojom::blink::WebBluetoothResult::SUCCESS) {
DCHECK(value);
DOMDataView* dom_data_view = DOMDataView* dom_data_view =
BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(value.value()); BluetoothRemoteGATTUtils::ConvertSpanToDataView(value);
SetValue(dom_data_view); SetValue(dom_data_view);
if (notification_registration_in_progress()) { if (notification_registration_in_progress()) {
// Save event to be dispatched after notification is registered. // Save event to be dispatched after notification is registered.
@@ -161,7 +160,7 @@ BluetoothRemoteGATTCharacteristic::readValue(ScriptState* script_state,
void BluetoothRemoteGATTCharacteristic::WriteValueCallback( void BluetoothRemoteGATTCharacteristic::WriteValueCallback(
ScriptPromiseResolver<IDLUndefined>* resolver, ScriptPromiseResolver<IDLUndefined>* resolver,
const Vector<uint8_t>& value, DOMDataView* new_value,
mojom::blink::WebBluetoothResult result) { mojom::blink::WebBluetoothResult result) {
if (!resolver->GetExecutionContext() || if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed()) resolver->GetExecutionContext()->IsContextDestroyed())
@@ -175,7 +174,7 @@ void BluetoothRemoteGATTCharacteristic::WriteValueCallback(
} }
if (result == mojom::blink::WebBluetoothResult::SUCCESS) { if (result == mojom::blink::WebBluetoothResult::SUCCESS) {
SetValue(BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(value)); SetValue(new_value);
resolver->Resolve(); resolver->Resolve();
} else { } else {
resolver->Reject(BluetoothError::CreateDOMException(result)); resolver->Reject(BluetoothError::CreateDOMException(result));
@@ -217,9 +216,9 @@ BluetoothRemoteGATTCharacteristic::WriteCharacteristicValue(
return EmptyPromise(); return EmptyPromise();
} }
// Let valueVector be a copy of the bytes held by value. // Let newValue be a copy of the bytes held by value.
Vector<uint8_t> value_vector; DOMDataView* new_value =
value_vector.AppendSpan(value); BluetoothRemoteGATTUtils::ConvertSpanToDataView(value);
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLUndefined>>( auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLUndefined>>(
script_state, exception_state.GetContext()); script_state, exception_state.GetContext());
@@ -228,10 +227,10 @@ BluetoothRemoteGATTCharacteristic::WriteCharacteristicValue(
mojom::blink::WebBluetoothService* service = GetBluetooth()->Service(); mojom::blink::WebBluetoothService* service = GetBluetooth()->Service();
service->RemoteCharacteristicWriteValue( service->RemoteCharacteristicWriteValue(
characteristic_->instance_id, value_vector, write_type, characteristic_->instance_id, value, write_type,
WTF::BindOnce(&BluetoothRemoteGATTCharacteristic::WriteValueCallback, WTF::BindOnce(&BluetoothRemoteGATTCharacteristic::WriteValueCallback,
WrapPersistent(this), WrapPersistent(resolver), WrapPersistent(this), WrapPersistent(resolver),
value_vector)); WrapPersistent(new_value)));
return promise; return promise;
} }

@@ -56,7 +56,7 @@ class BluetoothRemoteGATTCharacteristic final
// mojom::blink::WebBluetoothCharacteristicClient: // mojom::blink::WebBluetoothCharacteristicClient:
void RemoteCharacteristicValueChanged( void RemoteCharacteristicValueChanged(
const WTF::Vector<uint8_t>& value) override; base::span<const uint8_t> value) override;
// ExecutionContextLifecycleObserver interface. // ExecutionContextLifecycleObserver interface.
void ContextDestroyed() override {} void ContextDestroyed() override {}
@@ -141,9 +141,9 @@ class BluetoothRemoteGATTCharacteristic final
void ReadValueCallback(ScriptPromiseResolver<NotShared<DOMDataView>>*, void ReadValueCallback(ScriptPromiseResolver<NotShared<DOMDataView>>*,
mojom::blink::WebBluetoothResult, mojom::blink::WebBluetoothResult,
const std::optional<Vector<uint8_t>>& value); base::span<const uint8_t> value);
void WriteValueCallback(ScriptPromiseResolver<IDLUndefined>*, void WriteValueCallback(ScriptPromiseResolver<IDLUndefined>*,
const Vector<uint8_t>& value, DOMDataView* new_value,
mojom::blink::WebBluetoothResult); mojom::blink::WebBluetoothResult);
// Callback for startNotifictions/stopNotifications. // Callback for startNotifictions/stopNotifications.

@@ -26,7 +26,7 @@ BluetoothRemoteGATTDescriptor::BluetoothRemoteGATTDescriptor(
void BluetoothRemoteGATTDescriptor::ReadValueCallback( void BluetoothRemoteGATTDescriptor::ReadValueCallback(
ScriptPromiseResolver<NotShared<DOMDataView>>* resolver, ScriptPromiseResolver<NotShared<DOMDataView>>* resolver,
mojom::blink::WebBluetoothResult result, mojom::blink::WebBluetoothResult result,
const std::optional<Vector<uint8_t>>& value) { base::span<const uint8_t> value) {
if (!resolver->GetExecutionContext() || if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed()) resolver->GetExecutionContext()->IsContextDestroyed())
return; return;
@@ -39,9 +39,8 @@ void BluetoothRemoteGATTDescriptor::ReadValueCallback(
} }
if (result == mojom::blink::WebBluetoothResult::SUCCESS) { if (result == mojom::blink::WebBluetoothResult::SUCCESS) {
DCHECK(value);
DOMDataView* dom_data_view = DOMDataView* dom_data_view =
BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(value.value()); BluetoothRemoteGATTUtils::ConvertSpanToDataView(value);
value_ = dom_data_view; value_ = dom_data_view;
resolver->Resolve(NotShared(dom_data_view)); resolver->Resolve(NotShared(dom_data_view));
} else { } else {
@@ -81,7 +80,7 @@ ScriptPromise<NotShared<DOMDataView>> BluetoothRemoteGATTDescriptor::readValue(
void BluetoothRemoteGATTDescriptor::WriteValueCallback( void BluetoothRemoteGATTDescriptor::WriteValueCallback(
ScriptPromiseResolver<IDLUndefined>* resolver, ScriptPromiseResolver<IDLUndefined>* resolver,
const Vector<uint8_t>& value, DOMDataView* new_value,
mojom::blink::WebBluetoothResult result) { mojom::blink::WebBluetoothResult result) {
if (!resolver->GetExecutionContext() || if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed()) resolver->GetExecutionContext()->IsContextDestroyed())
@@ -96,7 +95,7 @@ void BluetoothRemoteGATTDescriptor::WriteValueCallback(
} }
if (result == mojom::blink::WebBluetoothResult::SUCCESS) { if (result == mojom::blink::WebBluetoothResult::SUCCESS) {
value_ = BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(value); value_ = new_value;
resolver->Resolve(); resolver->Resolve();
} else { } else {
resolver->Reject(BluetoothError::CreateDOMException(result)); resolver->Reject(BluetoothError::CreateDOMException(result));
@@ -134,19 +133,19 @@ ScriptPromise<IDLUndefined> BluetoothRemoteGATTDescriptor::writeValue(
return EmptyPromise(); return EmptyPromise();
} }
// Let valueVector be a copy of the bytes held by value. // Let newValue be a copy of the bytes held by value.
Vector<uint8_t> value_vector; DOMDataView* new_value =
value_vector.AppendSpan(value); BluetoothRemoteGATTUtils::ConvertSpanToDataView(value);
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLUndefined>>( auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLUndefined>>(
script_state, exception_state.GetContext()); script_state, exception_state.GetContext());
auto promise = resolver->Promise(); auto promise = resolver->Promise();
GetGatt()->AddToActiveAlgorithms(resolver); GetGatt()->AddToActiveAlgorithms(resolver);
GetBluetooth()->Service()->RemoteDescriptorWriteValue( GetBluetooth()->Service()->RemoteDescriptorWriteValue(
descriptor_->instance_id, value_vector, descriptor_->instance_id, value,
WTF::BindOnce(&BluetoothRemoteGATTDescriptor::WriteValueCallback, WTF::BindOnce(&BluetoothRemoteGATTDescriptor::WriteValueCallback,
WrapPersistent(this), WrapPersistent(resolver), WrapPersistent(this), WrapPersistent(resolver),
value_vector)); WrapPersistent(new_value)));
return promise; return promise;
} }

@@ -61,10 +61,10 @@ class BluetoothRemoteGATTDescriptor final : public ScriptWrappable {
void ReadValueCallback(ScriptPromiseResolver<NotShared<DOMDataView>>*, void ReadValueCallback(ScriptPromiseResolver<NotShared<DOMDataView>>*,
mojom::blink::WebBluetoothResult, mojom::blink::WebBluetoothResult,
const std::optional<Vector<uint8_t>>&); base::span<const uint8_t>);
void WriteValueCallback(ScriptPromiseResolver<IDLUndefined>*, void WriteValueCallback(ScriptPromiseResolver<IDLUndefined>*,
const Vector<uint8_t>&, DOMDataView* new_value,
mojom::blink::WebBluetoothResult); mojom::blink::WebBluetoothResult);
String CreateInvalidDescriptorErrorMessage(); String CreateInvalidDescriptorErrorMessage();

@@ -7,12 +7,11 @@
namespace blink { namespace blink {
// static // static
DOMDataView* BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView( DOMDataView* BluetoothRemoteGATTUtils::ConvertSpanToDataView(
const WTF::Vector<uint8_t>& wtf_vector) { base::span<const uint8_t> span) {
static_assert(sizeof(*wtf_vector.data()) == 1, static_assert(sizeof(*span.data()) == 1, "uint8_t should be a single byte");
"uint8_t should be a single byte"); DOMArrayBuffer* dom_buffer = DOMArrayBuffer::Create(span);
DOMArrayBuffer* dom_buffer = DOMArrayBuffer::Create(wtf_vector); return DOMDataView::Create(dom_buffer, 0, span.size());
return DOMDataView::Create(dom_buffer, 0, wtf_vector.size());
} }
} // namespace blink } // namespace blink

@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_UTILS_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_UTILS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_UTILS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_UTILS_H_
#include "base/containers/span.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" #include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink { namespace blink {
@@ -15,7 +15,7 @@ class BluetoothRemoteGATTUtils final {
STATIC_ONLY(BluetoothRemoteGATTUtils); STATIC_ONLY(BluetoothRemoteGATTUtils);
public: public:
static DOMDataView* ConvertWTFVectorToDataView(const WTF::Vector<uint8_t>&); static DOMDataView* ConvertSpanToDataView(base::span<const uint8_t>);
}; };
} // namespace blink } // namespace blink

@@ -24,7 +24,7 @@ class BluetoothServiceDataMapIterationSource final
return false; return false;
map_key = iterator_->key; map_key = iterator_->key;
map_value = NotShared<DOMDataView>( map_value = NotShared<DOMDataView>(
BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(iterator_->value)); BluetoothRemoteGATTUtils::ConvertSpanToDataView(iterator_->value));
++iterator_; ++iterator_;
return true; return true;
} }
@@ -60,7 +60,7 @@ bool BluetoothServiceDataMap::GetMapEntry(ScriptState*,
return false; return false;
DOMDataView* dom_data_view = DOMDataView* dom_data_view =
BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(it->value); BluetoothRemoteGATTUtils::ConvertSpanToDataView(it->value);
value = NotShared<DOMDataView>(dom_data_view); value = NotShared<DOMDataView>(dom_data_view);
return true; return true;