Commit bfd3bf43 authored by Qiyu Hu's avatar Qiyu Hu Committed by Commit Bot

arc: bluetooth: Add EIR as part of OnLEDeviceFound

On each LE advertisement event, we forward the event along with the EIR
such that it's closer to the behavior in Android.

Please review along with ag/5453291

Bug: chromium:887029,b:118334521
Test: CtsVerifier
Change-Id: I4f56ef5e30087768acb7e897c5345380ffb7a633
Reviewed-on: https://chromium-review.googlesource.com/c/1321581Reviewed-by: default avatarGreg Kerr <kerrnel@chromium.org>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Reviewed-by: default avatarHidehiko Abe <hidehiko@chromium.org>
Commit-Queue: Qiyu Hu <qiyuh@google.com>
Cr-Commit-Position: refs/heads/master@{#607362}
parent 3bf97c16
......@@ -24,6 +24,7 @@
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
......@@ -70,6 +71,16 @@ using device::BluetoothUUID;
namespace {
base::Optional<int> SdkVersion() {
constexpr char kVersionKey[] = "CHROMEOS_ARC_ANDROID_SDK_VERSION";
int sdk_version;
std::string sdk_str;
if (!base::SysInfo::GetLsbReleaseValue(kVersionKey, &sdk_str) ||
!base::StringToInt(sdk_str, &sdk_version))
return base::nullopt;
return sdk_version;
}
// https://android.googlesource.com/platform/system/bt/+/master/stack/include/gatt_api.h
constexpr int32_t GATT_CHAR_PROP_BIT_BROADCAST = (1 << 0);
constexpr int32_t GATT_CHAR_PROP_BIT_READ = (1 << 1);
......@@ -496,25 +507,17 @@ void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter,
if (!arc_bridge_service_->bluetooth()->IsConnected())
return;
auto* device_found = ARC_GET_INSTANCE_FOR_METHOD(
auto* bluetooth_instance = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->bluetooth(), OnDeviceFound);
if (device_found) {
device_found->OnDeviceFound(
if (bluetooth_instance) {
bluetooth_instance->OnDeviceFound(
GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device));
}
if (!(device->GetType() & device::BLUETOOTH_TRANSPORT_LE))
return;
base::Optional<int8_t> rssi = device->GetInquiryRSSI();
std::string addr = device->GetAddress();
auto* le_device_found = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->bluetooth(), OnLEDeviceFound);
if (le_device_found && rssi.has_value()) {
le_device_found->OnLEDeviceFound(mojom::BluetoothAddress::From(addr),
rssi.value(), GetAdvertisingData(device));
}
auto it = gatt_connections_.find(addr);
bool was_connected =
(it != gatt_connections_.end() &&
......@@ -599,6 +602,33 @@ void ArcBluetoothBridge::DeviceMTUChanged(BluetoothAdapter* adapter,
mojom::BluetoothAddress::From(device->GetAddress()), mtu);
}
void ArcBluetoothBridge::DeviceAdvertisementReceived(
BluetoothAdapter* adapter,
BluetoothDevice* device,
int16_t rssi,
const std::vector<uint8_t>& eir) {
constexpr int kAndroidPSdkVersion = 28;
base::Optional<int> sdk_version = SdkVersion();
mojom::BluetoothAddressPtr addr =
mojom::BluetoothAddress::From(device->GetAddress());
if (!sdk_version)
return;
if (sdk_version.value() >= kAndroidPSdkVersion) {
auto* bluetooth_instance = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->bluetooth(), OnLEDeviceFound);
if (bluetooth_instance)
bluetooth_instance->OnLEDeviceFound(std::move(addr), rssi, eir);
return;
}
auto* bluetooth_instance = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->bluetooth(), OnLEDeviceFoundForN);
if (bluetooth_instance)
bluetooth_instance->OnLEDeviceFoundForN(std::move(addr), rssi,
GetAdvertisingData(device));
}
void ArcBluetoothBridge::DeviceRemoved(BluetoothAdapter* adapter,
BluetoothDevice* device) {
if (!arc_bridge_service_->bluetooth()->IsConnected())
......
......@@ -94,6 +94,11 @@ class ArcBluetoothBridge
device::BluetoothDevice* device,
uint16_t mtu) override;
void DeviceAdvertisementReceived(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device,
int16_t rssi,
const std::vector<uint8_t>& eir) override;
void DeviceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
......
......@@ -12,6 +12,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/bluetooth/bluetooth_type_converters.h"
#include "components/arc/common/bluetooth.mojom.h"
......@@ -31,6 +32,7 @@ namespace {
constexpr int16_t kTestRssi = -50;
constexpr int16_t kTestRssi2 = -70;
constexpr char kTestServiceUUID[] = "00001357-0000-1000-8000-00805f9b34fb";
const std::vector<uint8_t> kEIR = {0x00, 0x01, 0x02};
} // namespace
namespace arc {
......@@ -58,6 +60,9 @@ class ArcBluetoothBridgeTest : public testing::Test {
dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath),
{kTestServiceUUID}, /* service_data = */ {},
/* manufacture_data = */ {});
fake_bluetooth_device_client->UpdateEIR(
dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath),
kEIR);
fake_bluetooth_gatt_service_client->ExposeHeartRateService(
dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
fake_bluetooth_gatt_characteristic_client->ExposeHeartRateCharacteristics(
......@@ -102,7 +107,9 @@ class ArcBluetoothBridgeTest : public testing::Test {
nullptr, arc_bridge_service_.get());
fake_bluetooth_instance_ = std::make_unique<FakeBluetoothInstance>();
arc_bridge_service_->bluetooth()->SetInstance(
fake_bluetooth_instance_.get(), 2);
fake_bluetooth_instance_.get(), 13);
base::SysInfo::SetChromeOSVersionInfoForTest(
"CHROMEOS_ARC_ANDROID_SDK_VERSION=28", base::Time::Now());
WaitForInstanceReady(arc_bridge_service_->bluetooth());
device::BluetoothAdapterFactory::GetAdapter(base::Bind(
......@@ -256,6 +263,29 @@ TEST_F(ArcBluetoothBridgeTest, LEDeviceFound) {
AddTestDevice();
EXPECT_EQ(1u, fake_bluetooth_instance_->le_device_found_data().size());
const auto& le_device_found_data =
fake_bluetooth_instance_->le_device_found_data().back();
const mojom::BluetoothAddressPtr& addr = le_device_found_data->addr();
const std::vector<uint8_t>& eir = le_device_found_data->eir();
EXPECT_EQ(std::string(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress),
addr->To<std::string>());
EXPECT_EQ(kEIR, eir);
EXPECT_EQ(kTestRssi, le_device_found_data->rssi());
ChangeTestDeviceRssi(kTestRssi2);
EXPECT_EQ(2u, fake_bluetooth_instance_->le_device_found_data().size());
EXPECT_EQ(kTestRssi2,
fake_bluetooth_instance_->le_device_found_data().back()->rssi());
}
TEST_F(ArcBluetoothBridgeTest, LEDeviceFoundForN) {
base::SysInfo::SetChromeOSVersionInfoForTest(
"CHROMEOS_ARC_ANDROID_SDK_VERSION=27", base::Time::Now());
EXPECT_EQ(0u, fake_bluetooth_instance_->le_device_found_data().size());
AddTestDevice();
EXPECT_EQ(1u, fake_bluetooth_instance_->le_device_found_data().size());
const auto& le_device_found_data =
fake_bluetooth_instance_->le_device_found_data().back();
const mojom::BluetoothAddressPtr& addr = le_device_found_data->addr();
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Next MinVersion: 13
// Next MinVersion: 14
module arc.mojom;
......@@ -401,7 +401,7 @@ interface BluetoothHost {
=> (BluetoothGattStatus status);
};
// Next Method ID: 21
// Next Method ID: 22
// Deprecated Method ID: 2
interface BluetoothInstance {
// DEPRECATED: Please use Init@18 instead.
......@@ -422,9 +422,14 @@ interface BluetoothInstance {
BluetoothAclState state);
// Bluetooth Gatt Client callbacks
[MinVersion=1] OnLEDeviceFound@7(BluetoothAddress addr,
int32 rssi,
array<BluetoothAdvertisingData> adv_data);
// TODO(b/111367421): Remove this when no active device running Android N.
[MinVersion=1] OnLEDeviceFoundForN@7(
BluetoothAddress addr,
int32 rssi,
array<BluetoothAdvertisingData> adv_data);
[MinVersion=13] OnLEDeviceFound@21(BluetoothAddress addr,
int32 rssi,
array<uint8> eir);
[MinVersion=1] OnLEConnectionStateChange@8(BluetoothAddress remote_addr,
bool connected);
[MinVersion=4] OnLEDeviceAddressChange@16(BluetoothAddress old_addr,
......
......@@ -21,10 +21,14 @@ FakeBluetoothInstance::GattDBResult::GattDBResult(
FakeBluetoothInstance::GattDBResult::~GattDBResult() {}
FakeBluetoothInstance::LEDeviceFoundData::LEDeviceFoundData(
mojom::BluetoothAddressPtr&& addr,
mojom::BluetoothAddressPtr addr,
int32_t rssi,
std::vector<mojom::BluetoothAdvertisingDataPtr>&& adv_data)
: addr_(std::move(addr)), rssi_(rssi), adv_data_(std::move(adv_data)) {}
std::vector<mojom::BluetoothAdvertisingDataPtr> adv_data,
const std::vector<uint8_t>& eir)
: addr_(std::move(addr)),
rssi_(rssi),
adv_data_(std::move(adv_data)),
eir_(std::move(eir)) {}
FakeBluetoothInstance::LEDeviceFoundData::~LEDeviceFoundData() {}
......@@ -60,12 +64,20 @@ void FakeBluetoothInstance::OnAclStateChanged(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothAclState state) {}
void FakeBluetoothInstance::OnLEDeviceFound(
void FakeBluetoothInstance::OnLEDeviceFoundForN(
mojom::BluetoothAddressPtr addr,
int32_t rssi,
std::vector<mojom::BluetoothAdvertisingDataPtr> adv_data) {
le_device_found_data_.push_back(std::make_unique<LEDeviceFoundData>(
std::move(addr), rssi, std::move(adv_data)));
std::move(addr), rssi, std::move(adv_data), std::vector<uint8_t>()));
}
void FakeBluetoothInstance::OnLEDeviceFound(mojom::BluetoothAddressPtr addr,
int32_t rssi,
const std::vector<uint8_t>& eir) {
le_device_found_data_.push_back(std::make_unique<LEDeviceFoundData>(
std::move(addr), rssi, std::vector<mojom::BluetoothAdvertisingDataPtr>(),
eir));
}
void FakeBluetoothInstance::OnLEConnectionStateChange(
......
......@@ -43,10 +43,10 @@ class FakeBluetoothInstance : public mojom::BluetoothInstance {
class LEDeviceFoundData {
public:
LEDeviceFoundData(
mojom::BluetoothAddressPtr&& addr,
int32_t rssi,
std::vector<mojom::BluetoothAdvertisingDataPtr>&& adv_data);
LEDeviceFoundData(mojom::BluetoothAddressPtr addr,
int32_t rssi,
std::vector<mojom::BluetoothAdvertisingDataPtr> adv_data,
const std::vector<uint8_t>& eir);
~LEDeviceFoundData();
const mojom::BluetoothAddressPtr& addr() const { return addr_; }
......@@ -57,10 +57,13 @@ class FakeBluetoothInstance : public mojom::BluetoothInstance {
return adv_data_;
}
const std::vector<uint8_t>& eir() const { return eir_; }
private:
mojom::BluetoothAddressPtr addr_;
int32_t rssi_;
std::vector<mojom::BluetoothAdvertisingDataPtr> adv_data_;
std::vector<uint8_t> eir_;
DISALLOW_COPY_AND_ASSIGN(LEDeviceFoundData);
};
......@@ -83,10 +86,13 @@ class FakeBluetoothInstance : public mojom::BluetoothInstance {
void OnAclStateChanged(mojom::BluetoothStatus status,
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothAclState state) override;
void OnLEDeviceFound(
void OnLEDeviceFoundForN(
mojom::BluetoothAddressPtr addr,
int32_t rssi,
std::vector<mojom::BluetoothAdvertisingDataPtr> adv_data) override;
void OnLEDeviceFound(mojom::BluetoothAddressPtr addr,
int32_t rssi,
const std::vector<uint8_t>& eir) override;
void OnLEConnectionStateChange(mojom::BluetoothAddressPtr remote_addr,
bool connected) override;
void OnLEDeviceAddressChange(mojom::BluetoothAddressPtr old_addr,
......
......@@ -1631,6 +1631,19 @@ void FakeBluetoothDeviceClient::UpdateServiceAndManufacturerData(
properties->manufacturer_data.ReplaceValue(merged_manufacturer_data);
}
void FakeBluetoothDeviceClient::UpdateEIR(const dbus::ObjectPath& object_path,
const std::vector<uint8_t>& eir) {
PropertiesMap::const_iterator iter = properties_map_.find(object_path);
if (iter == properties_map_.end()) {
VLOG(2) << "Fake device does not exist: " << object_path.value();
return;
}
Properties* properties = iter->second.get();
DCHECK(properties);
properties->eir.set_valid(true);
properties->eir.ReplaceValue(eir);
}
void FakeBluetoothDeviceClient::UpdateConnectionInfo(
uint16_t connection_rssi,
uint16_t transmit_power,
......
......@@ -195,6 +195,11 @@ class DEVICE_BLUETOOTH_EXPORT FakeBluetoothDeviceClient
const std::map<std::string, std::vector<uint8_t>>& service_data,
const std::map<uint16_t, std::vector<uint8_t>>& manufacturer_data);
// Updates the EIR property of fake device with object path |object_path| to
// |eir|, if the fake device exists.
void UpdateEIR(const dbus::ObjectPath& object_path,
const std::vector<uint8_t>& eir);
// Adds a pending prepare write request to |object_path|.
void AddPrepareWriteRequest(const dbus::ObjectPath& object_path,
const std::vector<uint8_t>& value);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment