Skip to content

Commit

Permalink
Call the BLE scan parser service to parse BLE advertisement packets i…
Browse files Browse the repository at this point in the history
…n bluez.

Bug: 974844
Change-Id: If4c07ecfa2e80ab1c0e8122296b3ff36352d8987
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1666089
Commit-Queue: Jason Majors <jmajors@google.com>
Reviewed-by: Bo <boliu@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#685069}
  • Loading branch information
Jason Majors authored and Commit Bot committed Aug 8, 2019
1 parent 7ac21d9 commit ccd96eb
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 20 deletions.
2 changes: 2 additions & 0 deletions content/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1981,6 +1981,8 @@ jumbo_source_set("browser") {
deps += [
"//chromeos/resources",
"//components/chromeos_camera:mojo_mjpeg_decode_accelerator",
"//services/data_decoder/public/cpp",
"//services/data_decoder/public/mojom",
]
}

Expand Down
1 change: 1 addition & 0 deletions content/browser/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ include_rules = [
"+content/public/app",
"+content/public/browser",
"+device/base/synchronization",
"+device/bluetooth",
"+device/gamepad", # For gamepad API
"+device/nfc",
"+device/vr", # For WebVR API
Expand Down
17 changes: 16 additions & 1 deletion content/browser/browser_main_loop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@
#if defined(OS_CHROMEOS)
#include "base/memory/memory_pressure_monitor_chromeos.h"
#include "chromeos/constants/chromeos_switches.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "services/data_decoder/public/mojom/constants.mojom.h"
#endif

#if defined(USE_GLIB)
Expand Down Expand Up @@ -389,6 +391,16 @@ std::unique_ptr<base::MemoryPressureMonitor> CreateMemoryPressureMonitor(
#endif
}

#if defined(OS_CHROMEOS)
mojo::PendingRemote<data_decoder::mojom::BleScanParser> GetBleScanParser() {
mojo::PendingRemote<data_decoder::mojom::BleScanParser> ble_scan_parser;
GetSystemConnector()->Connect(
data_decoder::mojom::kServiceName,
ble_scan_parser.InitWithNewPipeAndPassReceiver());
return ble_scan_parser;
}
#endif // defined(OS_CHROMEOS)

} // namespace

#if defined(USE_X11)
Expand Down Expand Up @@ -773,7 +785,10 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
sql::SqlMemoryDumpProvider::GetInstance(), "Sql", nullptr);
#if !defined(OS_CHROMEOS)
#if defined(OS_CHROMEOS)
device::BluetoothAdapterFactory::SetBleScanParserCallback(
base::BindRepeating(&GetBleScanParser));
#else
// Chrome Remote Desktop needs TransitionalURLLoaderFactoryOwner on ChromeOS.
network::TransitionalURLLoaderFactoryOwner::DisallowUsageInProcess();
#endif
Expand Down
20 changes: 13 additions & 7 deletions content/public/app/content_browser_manifest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@
namespace content {

const service_manager::Manifest& GetContentBrowserManifest() {
// clang-format off
static base::NoDestructor<service_manager::Manifest> manifest{
service_manager::ManifestBuilder()
.WithServiceName(mojom::kBrowserServiceName)
.WithDisplayName("Content (browser process)")
.WithOptions(service_manager::ManifestOptionsBuilder()
.CanConnectToInstancesInAnyGroup(true)
.CanConnectToInstancesWithAnyId(true)
.CanRegisterOtherServiceInstances(true)
.Build())
.CanConnectToInstancesInAnyGroup(true)
.CanConnectToInstancesWithAnyId(true)
.CanRegisterOtherServiceInstances(true)
.Build())
.ExposeCapability("field_trials",
std::set<const char*>{
"content.mojom.FieldTrialRecorder",
Expand Down Expand Up @@ -109,6 +110,9 @@ const service_manager::Manifest& GetContentBrowserManifest() {
.RequireCapability("data_decoder", "image_decoder")
.RequireCapability("data_decoder", "json_parser")
.RequireCapability("data_decoder", "xml_parser")
#if defined(OS_CHROMEOS)
.RequireCapability("data_decoder", "ble_scan_parser")
#endif // OS_CHROMEOS
.RequireCapability("cdm", "media:cdm")
.RequireCapability("shape_detection", "barcode_detection")
.RequireCapability("shape_detection", "face_detection")
Expand All @@ -123,7 +127,7 @@ const service_manager::Manifest& GetContentBrowserManifest() {
.RequireCapability("content", "navigation")
.RequireCapability("resource_coordinator", "service_callbacks")
.RequireCapability("service_manager",
"service_manager:service_manager")
"service_manager:service_manager")
.RequireCapability("chromecast", "multizone")
.RequireCapability("content_plugin", "browser")
.RequireCapability("metrics", "url_keyed_metrics")
Expand Down Expand Up @@ -182,8 +186,9 @@ const service_manager::Manifest& GetContentBrowserManifest() {
"blink.mojom.NotificationService",
"blink.mojom.PermissionService",
"blink.mojom.QuotaDispatcherHost",
"blink.mojom.SerialService", "blink.mojom.WebUsbService",
"blink.mojom.SmsReceiver", "blink.mojom.WebSocketConnector",
"blink.mojom.SerialService",
"blink.mojom.WebUsbService", "blink.mojom.SmsReceiver",
"blink.mojom.WebSocketConnector",
"media.mojom.VideoDecodePerfHistory",
"payments.mojom.PaymentManager",
"shape_detection.mojom.BarcodeDetectionProvider",
Expand Down Expand Up @@ -284,6 +289,7 @@ const service_manager::Manifest& GetContentBrowserManifest() {
.PackageService(file::GetManifest())
.Build()};
return *manifest;
// clang-format on
}

} // namespace content
1 change: 1 addition & 0 deletions device/bluetooth/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ component("bluetooth") {
"chromeos/bluetooth_utils.cc",
"chromeos/bluetooth_utils.h",
]
deps += [ "//services/data_decoder/public/mojom" ]
}
deps += [ "//dbus" ]
} else { # !use_dbus
Expand Down
1 change: 1 addition & 0 deletions device/bluetooth/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ include_rules = [
"+net/log",
"+net/socket",
"+net/traffic_annotation",
"+services/data_decoder/public/mojom",
"+ui/base/l10n",
"+third_party/cros_system_api/dbus",
"+third_party/re2",
Expand Down
14 changes: 14 additions & 0 deletions device/bluetooth/bluetooth_adapter_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,20 @@ bool BluetoothAdapterFactory::HasSharedInstanceForTesting() {
return default_adapter.Get() != nullptr;
}

#if defined(OS_CHROMEOS)
// static
void BluetoothAdapterFactory::SetBleScanParserCallback(
BleScanParserCallback callback) {
Get().ble_scan_parser_ = callback;
}

// static
BluetoothAdapterFactory::BleScanParserCallback
BluetoothAdapterFactory::GetBleScanParserCallback() {
return Get().ble_scan_parser_;
}
#endif // defined(OS_CHROMEOS)

BluetoothAdapterFactory::GlobalValuesForTesting::GlobalValuesForTesting()
: weak_ptr_factory_(this) {}

Expand Down
22 changes: 22 additions & 0 deletions device/bluetooth/bluetooth_adapter_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_export.h"

#if defined(OS_CHROMEOS)
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/data_decoder/public/mojom/ble_scan_parser.mojom.h"
#endif // defined(OS_CHROMEOS)

namespace device {

// A factory class for building a Bluetooth adapter on platforms where Bluetooth
Expand All @@ -30,6 +35,11 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterFactory {
using AdapterCallback =
base::OnceCallback<void(scoped_refptr<BluetoothAdapter> adapter)>;

#if defined(OS_CHROMEOS)
using BleScanParserCallback = base::RepeatingCallback<
mojo::PendingRemote<data_decoder::mojom::BleScanParser>()>;
#endif // defined(OS_CHROMEOS)

~BluetoothAdapterFactory();

static BluetoothAdapterFactory& Get();
Expand Down Expand Up @@ -75,6 +85,14 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterFactory {
// adapter. Exposed for testing.
static bool HasSharedInstanceForTesting();

#if defined(OS_CHROMEOS)
// Sets the BleScanParserPtr callback used in Get*() below.
static void SetBleScanParserCallback(BleScanParserCallback callback);
// Returns a reference to a parser for BLE advertisement packets.
// This will be an empty callback until something calls Set*() above.
static BleScanParserCallback GetBleScanParserCallback();
#endif // defined(OS_CHROMEOS)

// ValuestForTesting holds the return values for BluetoothAdapterFactory's
// functions that have been set for testing.
class DEVICE_BLUETOOTH_EXPORT GlobalValuesForTesting {
Expand Down Expand Up @@ -116,6 +134,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterFactory {
BluetoothAdapterFactory();

base::WeakPtr<GlobalValuesForTesting> values_for_testing_;

#if defined(OS_CHROMEOS)
BleScanParserCallback ble_scan_parser_;
#endif // defined(OS_CHROMEOS)
};

} // namespace device
Expand Down
72 changes: 72 additions & 0 deletions device/bluetooth/bluez/bluetooth_adapter_bluez.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@

#if defined(OS_CHROMEOS)
#include "chromeos/constants/devicetype.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/chromeos/bluetooth_utils.h"
#endif

Expand Down Expand Up @@ -105,6 +106,24 @@ UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA(
}
}

#if defined(OS_CHROMEOS)
device::BluetoothDevice::ServiceDataMap ConvertServiceDataMap(
const base::flat_map<std::string, std::vector<uint8_t>>& input) {
device::BluetoothDevice::ServiceDataMap output;
for (auto& i : input) {
output[BluetoothUUID(i.first)] = i.second;
}

return output;
}

device::BluetoothDevice::ManufacturerDataMap ConvertManufacturerDataMap(
const base::flat_map<uint16_t, std::vector<uint8_t>>& input) {
return device::BluetoothDevice::ManufacturerDataMap(input.begin(),
input.end());
}
#endif // defined(OS_CHROMEOS)

} // namespace

namespace device {
Expand Down Expand Up @@ -1187,8 +1206,37 @@ void BluetoothAdapterBlueZ::NotifyDeviceAdvertisementReceived(

for (auto& observer : observers_)
observer.DeviceAdvertisementReceived(this, device, rssi, eir);

#if defined(OS_CHROMEOS)
if (ble_scan_parser_.is_bound()) {
ScanRecordCallback callback =
base::BindOnce(&BluetoothAdapterBlueZ::OnAdvertisementReceived,
weak_ptr_factory_.GetWeakPtr(), device->GetAddress(),
device->GetName() ? *(device->GetName()) : std::string(),
rssi, device->GetAppearance());
ble_scan_parser_->Parse(eir, std::move(callback));
}
#endif // defined(OS_CHROMEOS)
}

#if defined(OS_CHROMEOS)
void BluetoothAdapterBlueZ::OnAdvertisementReceived(std::string device_address,
std::string device_name,
uint8_t rssi,
uint16_t device_appearance,
ScanRecordPtr scan_record) {
auto service_data_map = ConvertServiceDataMap(scan_record->service_data_map);
auto manufacturer_data_map =
ConvertManufacturerDataMap(scan_record->manufacturer_data_map);
for (auto& observer : observers_) {
observer.DeviceAdvertisementReceived(
device_address, device_name, scan_record->advertisement_name, rssi,
scan_record->tx_power, device_appearance, scan_record->service_uuids,
service_data_map, manufacturer_data_map);
}
}
#endif // defined(OS_CHROMEOS)

void BluetoothAdapterBlueZ::NotifyDeviceConnectedStateChanged(
BluetoothDeviceBlueZ* device,
bool is_now_connected) {
Expand Down Expand Up @@ -1515,6 +1563,26 @@ void BluetoothAdapterBlueZ::StartScanWithFilter(
return;
}

#if defined(OS_CHROMEOS)
device::BluetoothAdapterFactory::BleScanParserCallback
ble_scan_parser_callback =
device::BluetoothAdapterFactory::GetBleScanParserCallback();
if (ble_scan_parser_callback) {
// To avoid repeatedly restarting a crashed data decoder service,
// don't add a connection error handler here. Wait to establish a
// new connection after all discovery sessions are stopped.
ble_scan_parser_.Bind(ble_scan_parser_callback.Run());
} else {
#if DCHECK_IS_ON()
static bool logged_once = false;
DLOG_IF(ERROR, !logged_once)
<< "Attempted to connect to "
"unconfigured BluetoothAdapterFactory::GetBleScanParserCallback()";
logged_once = true;
#endif // DCHECK_IS_ON()
}
#endif // defined(OS_CHROMEOS)

auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));

if (discovery_filter) {
Expand Down Expand Up @@ -1593,6 +1661,10 @@ void BluetoothAdapterBlueZ::RemoveDiscoverySession(
return;
}

#if defined(OS_CHROMEOS)
ble_scan_parser_.reset();
#endif // defined(OS_CHROMEOS)

// There is exactly one active discovery session. Request BlueZ to stop
// discovery.
DCHECK_EQ(NumDiscoverySessions(), 1);
Expand Down
22 changes: 22 additions & 0 deletions device/bluetooth/bluez/bluetooth_adapter_bluez.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"

#if defined(OS_CHROMEOS)
#include "mojo/public/cpp/bindings/remote.h"
#include "services/data_decoder/public/mojom/ble_scan_parser.mojom.h"
#endif // defined(OS_CHROMEOS)

namespace base {
class TimeDelta;
} // namespace base
Expand Down Expand Up @@ -85,6 +90,11 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterBlueZ
using ServiceRecordErrorCallback =
base::Callback<void(BluetoothServiceRecordBlueZ::ErrorCode)>;

#if defined(OS_CHROMEOS)
using ScanRecordPtr = data_decoder::mojom::ScanRecordPtr;
using ScanRecordCallback = base::OnceCallback<void(ScanRecordPtr)>;
#endif // defined(OS_CHROMEOS)

// Calls |init_callback| after a BluetoothAdapter is fully initialized.
static base::WeakPtr<BluetoothAdapter> CreateAdapter(
InitCallback init_callback);
Expand Down Expand Up @@ -175,6 +185,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterBlueZ
int16_t rssi,
const std::vector<uint8_t>& eir);

#if defined(OS_CHROMEOS)
// Announce to observers advertisement received from |device|.
void OnAdvertisementReceived(std::string device_address,
std::string device_name,
uint8_t rssi,
uint16_t device_appearance,
ScanRecordPtr scan_record);
#endif // defined(OS_CHROMEOS)

// Announce to observers that |device| has changed its connected state.
void NotifyDeviceConnectedStateChanged(BluetoothDeviceBlueZ* device,
bool is_now_connected);
Expand Down Expand Up @@ -533,6 +552,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterBlueZ
// trials might not yet have been available. By scheduling a second update
// sometime later, the field trials will be guaranteed to be present.
base::OneShotTimer set_long_term_keys_after_first_time_install_timer_;

// Pointer for parsing BLE advertising packets out of process.
mojo::Remote<data_decoder::mojom::BleScanParser> ble_scan_parser_;
#endif

// Note: This should remain the last member so it'll be destroyed and
Expand Down

0 comments on commit ccd96eb

Please sign in to comment.