Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1067)

Unified Diff: components/arc/bluetooth/bluetooth_struct_traits.cc

Issue 2256003002: components/arc: implement multi advertising (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@plumb-incoming-connections
Patch Set: now using StructTraits/EnumTraits/UnionTraits/&c. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/arc/bluetooth/bluetooth_struct_traits.cc
diff --git a/components/arc/bluetooth/bluetooth_struct_traits.cc b/components/arc/bluetooth/bluetooth_struct_traits.cc
index 66691935a6e4cc67bc00e4436a687ed92f2960c1..7b8024f900e03bd4843c119c9f59a4f303066244 100644
--- a/components/arc/bluetooth/bluetooth_struct_traits.cc
+++ b/components/arc/bluetooth/bluetooth_struct_traits.cc
@@ -8,10 +8,13 @@
#include <vector>
#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "device/bluetooth/bluetooth_advertisement.h"
#include "device/bluetooth/bluetooth_uuid.h"
namespace {
+// BluetoothUUID helpers.
constexpr size_t kUUIDSize = 16;
bool IsNonHex(char c) {
@@ -26,6 +29,47 @@ std::string StripNonHex(const std::string& str) {
return result;
}
+// BluetoothAdvertisement helpers.
+struct AdvertisementEntry {
+ virtual void AddTo(device::BluetoothAdvertisement::Data* data) {}
+};
+
+struct ServiceUUIDEntry : public AdvertisementEntry {
+ std::vector<device::BluetoothUUID> service_uuids_;
Luis Héctor Chávez 2016/09/12 19:53:00 struct data members don't have trailing underscore
+
+ void AddTo(device::BluetoothAdvertisement::Data* data) override {
+ std::vector<std::string> string_uuids;
Luis Héctor Chávez 2016/09/12 19:53:00 Can you avoid one copy (in L45) by declaring |stri
+ for (const auto& uuid : service_uuids_) {
+ string_uuids.emplace_back(uuid.value());
+ }
+ data->set_service_uuids(
+ base::MakeUnique<std::vector<std::string>>(string_uuids));
+ }
+};
+
+struct ServiceDataEntry : public AdvertisementEntry {
+ uint16_t service_uuid_;
+ std::vector<uint8_t> service_data_;
+
+ void AddTo(device::BluetoothAdvertisement::Data* data) override {
+ std::string string_uuid = base::StringPrintf("%04x", service_uuid_);
+ data->set_service_data(
+ base::WrapUnique(new std::map<std::string, std::vector<uint8_t>>{
+ {string_uuid, service_data_}}));
+ }
+};
+
+struct ManufacturerDataEntry : public AdvertisementEntry {
+ uint16_t company_id_code_;
+ std::vector<uint8_t> blob_;
+
+ void AddTo(device::BluetoothAdvertisement::Data* data) override {
+ data->set_manufacturer_data(
+ base::WrapUnique(new std::map<uint16_t, std::vector<uint8_t>>{
+ {company_id_code_, blob_}}));
+ }
+};
+
} // namespace
namespace mojo {
@@ -67,4 +111,115 @@ bool StructTraits<arc::mojom::BluetoothUUIDDataView,
return true;
}
+template <>
+struct EnumTraits<arc::mojom::BluetoothAdvertisementType,
+ device::BluetoothAdvertisement::AdvertisementType> {
+ static bool FromMojom(
+ arc::mojom::BluetoothAdvertisementType mojom_type,
+ device::BluetoothAdvertisement::AdvertisementType* type) {
+ switch (mojom_type) {
+ case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_CONNECTABLE:
+ case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_SCANNABLE:
+ *type = device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_PERIPHERAL;
+ break;
+ case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_NON_CONNECTABLE:
+ *type = device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST;
+ break;
+ default:
Luis Héctor Chávez 2016/09/12 19:53:00 since |mojom_type| is a strongly-typed enum and we
+ NOTREACHED() << "Invalid type: " << static_cast<uint32_t>(mojom_type);
+ return false;
+ }
+ return true;
+ }
+};
+
+template <>
+struct StructTraits<arc::mojom::BluetoothServiceDataDataView,
+ ServiceDataEntry> {
+ static bool Read(arc::mojom::BluetoothServiceDataDataView data,
+ ServiceDataEntry* output) {
+ output->service_uuid_ = data.uuid_16bit();
+ data.ReadData(&output->service_data_);
+ return true;
+ }
+};
+
+template <>
+struct UnionTraits<arc::mojom::BluetoothAdvertisingDataDataView,
+ std::unique_ptr<AdvertisementEntry>> {
+ static bool Read(arc::mojom::BluetoothAdvertisingDataDataView data,
+ std::unique_ptr<AdvertisementEntry>* output) {
+ switch (data.tag()) {
+ case arc::mojom::BluetoothAdvertisingDataDataView::Tag::SERVICE_UUIDS: {
+ std::unique_ptr<ServiceUUIDEntry> service_uuids =
+ base::MakeUnique<ServiceUUIDEntry>();
+ data.ReadServiceUuids(&service_uuids->service_uuids_);
+ *output = std::move(service_uuids);
+ break;
+ }
+ case arc::mojom::BluetoothAdvertisingDataDataView::Tag::SERVICE_DATA: {
+ std::unique_ptr<ServiceDataEntry> service_data =
+ base::MakeUnique<ServiceDataEntry>();
+ data.ReadServiceData(service_data.get());
+ *output = std::move(service_data);
+ break;
+ }
+ case arc::mojom::BluetoothAdvertisingDataDataView::Tag::
+ MANUFACTURER_DATA: {
+ std::unique_ptr<ManufacturerDataEntry> manufacturer_data =
+ base::MakeUnique<ManufacturerDataEntry>();
+ // We get manufacturer data as a big blob. The first two bytes
+ // should be a company identifier code and the rest is manufacturer-
+ // specific.
+ std::vector<uint8_t> blob;
+ data.ReadManufacturerData(&blob);
+ if (blob.size() < sizeof(uint16_t)) {
+ LOG(WARNING) << "Advertisement had malformed manufacturer data";
+ return false;
+ }
+
+ // The company identifier code is in little-endian.
+ uint16_t company_id_code = blob[1] << 8 | blob[0];
Luis Héctor Chávez 2016/09/12 19:53:00 I've seen this snippet lots of times. Can you plea
Eric Caruso 2016/09/13 23:36:48 Where else does this occur in the Chrome codebase
Luis Héctor Chávez 2016/09/16 00:39:53 You're right, I was probably remembering the Andro
+ blob.erase(blob.begin(), blob.begin() + sizeof(uint16_t));
+ manufacturer_data->company_id_code_ = company_id_code;
+ manufacturer_data->blob_ = blob;
Luis Héctor Chávez 2016/09/12 19:53:00 Can you avoid a copy by using std::swap?
Eric Caruso 2016/09/13 23:36:48 operator=(std::vector<uint8_t>&&) should also work
+ *output = std::move(manufacturer_data);
+ break;
+ }
+ default: {
+ LOG(WARNING) << "Bluetooth advertising data case not implemented";
+ // Default AdvertisementEntry does nothing when added to the
+ // device::BluetoothAdvertisement::AdvertisementData, so data we
+ // don't know how to handle yet will be dropped but won't cause a
+ // failure to deserialize.
+ *output = base::MakeUnique<AdvertisementEntry>();
+ break;
+ }
+ }
+ return true;
+ }
+};
+
+// static
+bool StructTraits<arc::mojom::BluetoothAdvertisementDataView,
+ std::unique_ptr<device::BluetoothAdvertisement::Data>>::
+ Read(arc::mojom::BluetoothAdvertisementDataView advertisement,
+ std::unique_ptr<device::BluetoothAdvertisement::Data>* output) {
+ device::BluetoothAdvertisement::AdvertisementType adv_type;
+ if (!advertisement.ReadType(&adv_type))
+ return false;
+ auto data = base::MakeUnique<device::BluetoothAdvertisement::Data>(adv_type);
+
+ std::vector<std::unique_ptr<AdvertisementEntry>> adv_entries;
+ if (!advertisement.ReadData(&adv_entries))
+ return false;
+ for (const auto& adv_entry : adv_entries)
+ adv_entry->AddTo(data.get());
+
+ data->set_include_tx_power(advertisement.include_tx_power());
+
+ *output = std::move(data);
+ return true;
+}
+
} // namespace mojo
« no previous file with comments | « components/arc/bluetooth/bluetooth_struct_traits.h ('k') | components/arc/bluetooth/bluetooth_struct_traits_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698