[go: nahoru, domu]

[CrOS Bluetooth] Hide the non-discoverable LE devices

Check the advertisement flag for LE devices and hide those
non-discoverable ones.

Test=device_unittests and local test with non-discoverable HID device

Bug: b/296630816
Change-Id: I4efb2e3d729eaaffd0656a296404e21a0094cf71
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4833546
Reviewed-by: Gordon Seto <gordonseto@google.com>
Commit-Queue: Michael Sun <michaelfsun@google.com>
Cr-Commit-Position: refs/heads/main@{#1192853}
diff --git a/device/bluetooth/chromeos/bluetooth_utils.cc b/device/bluetooth/chromeos/bluetooth_utils.cc
index 0adc2c9c..ca5219c 100644
--- a/device/bluetooth/chromeos/bluetooth_utils.cc
+++ b/device/bluetooth/chromeos/bluetooth_utils.cc
@@ -42,6 +42,9 @@
 
 constexpr base::TimeDelta kMaxDeviceSelectionDuration = base::Seconds(30);
 
+constexpr uint8_t kLimitedDiscoveryFlag = 0x01;
+constexpr uint8_t kGeneralDiscoveryFlag = 0x02;
+
 // Get limited number of devices from |devices| and
 // prioritize paired/connecting devices over other devices.
 BluetoothAdapter::DeviceList GetLimitedNumDevices(
@@ -283,9 +286,17 @@
     // Device with invalid bluetooth transport is filtered out.
     case BLUETOOTH_TRANSPORT_INVALID:
       break;
-    // For LE devices, check the service UUID to determine if it supports HID
-    // or second factor authenticator (security key).
+    // For LE devices, check the discoverable flag and UUIDs.
     case BLUETOOTH_TRANSPORT_LE:
+      // Hide the LE device that mark itself as non-discoverble.
+      if (device->GetAdvertisingDataFlags().has_value()) {
+        if (!((kLimitedDiscoveryFlag | kGeneralDiscoveryFlag) &
+              device->GetAdvertisingDataFlags().value())) {
+          return true;
+        }
+      }
+      // Check the service UUID to determine if it supports HID or second factor
+      // authenticator (security key).
       if (base::Contains(device->GetUUIDs(),
                          device::BluetoothUUID(kHIDServiceUUID)) ||
           base::Contains(device->GetUUIDs(),
diff --git a/device/bluetooth/chromeos/bluetooth_utils_unittest.cc b/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
index d9b7829..3e40890 100644
--- a/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
+++ b/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
@@ -36,6 +36,10 @@
 constexpr char kHIDServiceUUID[] = "1812";
 constexpr char kSecurityKeyServiceUUID[] = "FFFD";
 constexpr char kUnexpectedServiceUUID[] = "1234";
+constexpr uint8_t kLimitedDiscoveryFlag = 0x01;
+constexpr uint8_t kGeneralDiscoveryFlag = 0x02;
+const BluetoothDevice::ServiceDataMap kTestServiceDataMap = {
+    {BluetoothUUID(kHIDServiceUUID), {1}}};
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Note: The first 3 hex bytes represent the OUI portion of the address, which
@@ -226,6 +230,45 @@
                                   0u /* num_expected_remaining_devices */);
 }
 
+TEST_F(
+    BluetoothUtilsTest,
+    TestFilterBluetoothDeviceList_FilterKnown_RemoveBleDevicesNonDiscoverable) {
+  auto* mock_bluetooth_device_1 =
+      AddMockBluetoothDeviceToAdapter(BLUETOOTH_TRANSPORT_LE);
+  mock_bluetooth_device_1->AddUUID(device::BluetoothUUID(kHIDServiceUUID));
+  mock_bluetooth_device_1->UpdateAdvertisementData(
+      1 /* rssi */, 0 /* flags */, BluetoothDevice::UUIDList(),
+      absl::nullopt /* tx_power */, kTestServiceDataMap,
+      BluetoothDevice::ManufacturerDataMap());
+
+  auto* mock_bluetooth_device_2 =
+      AddMockBluetoothDeviceToAdapter(BLUETOOTH_TRANSPORT_LE);
+  mock_bluetooth_device_2->AddUUID(device::BluetoothUUID(kHIDServiceUUID));
+  mock_bluetooth_device_2->UpdateAdvertisementData(
+      1 /* rssi */, kLimitedDiscoveryFlag /* flags */,
+      BluetoothDevice::UUIDList(), absl::nullopt /* tx_power */,
+      kTestServiceDataMap, BluetoothDevice::ManufacturerDataMap());
+
+  auto* mock_bluetooth_device_3 =
+      AddMockBluetoothDeviceToAdapter(BLUETOOTH_TRANSPORT_LE);
+  mock_bluetooth_device_3->AddUUID(device::BluetoothUUID(kHIDServiceUUID));
+  mock_bluetooth_device_3->UpdateAdvertisementData(
+      1 /* rssi */, kGeneralDiscoveryFlag /* flags */,
+      BluetoothDevice::UUIDList(), absl::nullopt /* tx_power */,
+      kTestServiceDataMap, BluetoothDevice::ManufacturerDataMap());
+
+  auto* mock_bluetooth_device_4 =
+      AddMockBluetoothDeviceToAdapter(BLUETOOTH_TRANSPORT_LE);
+  mock_bluetooth_device_4->AddUUID(device::BluetoothUUID(kHIDServiceUUID));
+  mock_bluetooth_device_4->UpdateAdvertisementData(
+      1 /* rssi */, kLimitedDiscoveryFlag | kGeneralDiscoveryFlag /* flags */,
+      BluetoothDevice::UUIDList(), absl::nullopt /* tx_power */,
+      kTestServiceDataMap, BluetoothDevice::ManufacturerDataMap());
+
+  VerifyFilterBluetoothDeviceList(BluetoothFilterType::KNOWN,
+                                  3u /* num_expected_remaining_devices */);
+}
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(
     BluetoothUtilsTest,