Commit 04cac696 authored by khorimoto's avatar khorimoto Committed by Commit bot

[CrOS Tether] Create BleScanner, a class which scan BLE advertisements and...

[CrOS Tether] Create BleScanner, a class which scan BLE advertisements and identifies nearby devices.

This class provides an API for registering or unregistering RemoteDevices. As long as at least one RemoteDevice is registered, a discovery session is active. If an advertisement from a registered RemoteDevice is scanned, observers are notified.

BUG=672263

Review-Url: https://codereview.chromium.org/2604063003
Cr-Commit-Position: refs/heads/master@{#441484}
parent c1bc970e
...@@ -10,6 +10,8 @@ static_library("tether") { ...@@ -10,6 +10,8 @@ static_library("tether") {
"ble_advertisement_device_queue.h", "ble_advertisement_device_queue.h",
"ble_constants.cc", "ble_constants.cc",
"ble_constants.h", "ble_constants.h",
"ble_scanner.cc",
"ble_scanner.h",
"host_scan_scheduler.cc", "host_scan_scheduler.cc",
"host_scan_scheduler.h", "host_scan_scheduler.h",
"host_scanner.cc", "host_scanner.cc",
...@@ -25,6 +27,7 @@ static_library("tether") { ...@@ -25,6 +27,7 @@ static_library("tether") {
"//chromeos", "//chromeos",
"//components/cryptauth", "//components/cryptauth",
"//components/proximity_auth/logging", "//components/proximity_auth/logging",
"//device/bluetooth",
] ]
public_deps = [ public_deps = [
...@@ -35,7 +38,10 @@ static_library("tether") { ...@@ -35,7 +38,10 @@ static_library("tether") {
static_library("test_support") { static_library("test_support") {
testonly = true testonly = true
sources = [] sources = [
"mock_local_device_data_provider.cc",
"mock_local_device_data_provider.h",
]
public_deps = [ public_deps = [
":tether", ":tether",
...@@ -43,6 +49,7 @@ static_library("test_support") { ...@@ -43,6 +49,7 @@ static_library("test_support") {
deps = [ deps = [
"//base", "//base",
"//components/cryptauth",
"//testing/gmock", "//testing/gmock",
] ]
} }
...@@ -52,6 +59,7 @@ source_set("unit_tests") { ...@@ -52,6 +59,7 @@ source_set("unit_tests") {
sources = [ sources = [
"ble_advertisement_device_queue_unittest.cc", "ble_advertisement_device_queue_unittest.cc",
"ble_scanner_unittest.cc",
"host_scan_scheduler_unittest.cc", "host_scan_scheduler_unittest.cc",
"local_device_data_provider_unittest.cc", "local_device_data_provider_unittest.cc",
] ]
...@@ -63,6 +71,8 @@ source_set("unit_tests") { ...@@ -63,6 +71,8 @@ source_set("unit_tests") {
"//chromeos", "//chromeos",
"//components/cryptauth", "//components/cryptauth",
"//components/cryptauth:test_support", "//components/cryptauth:test_support",
"//device/bluetooth",
"//device/bluetooth:mocks",
"//testing/gmock", "//testing/gmock",
"//testing/gtest", "//testing/gtest",
] ]
......
include_rules = [ include_rules = [
"+components/cryptauth", "+components/cryptauth",
"+components/proximity_auth/logging", "+components/proximity_auth/logging",
"+device/bluetooth",
] ]
...@@ -8,7 +8,7 @@ namespace chromeos { ...@@ -8,7 +8,7 @@ namespace chromeos {
namespace tether { namespace tether {
const int kMaxConcurrentAdvertisements = 2; const uint8_t kMaxConcurrentAdvertisements = 2;
const char kAdvertisingServiceUuid[] = "0000fe50-0000-1000-8000-00805f9b34fb"; const char kAdvertisingServiceUuid[] = "0000fe50-0000-1000-8000-00805f9b34fb";
} // namespace tether } // namespace tether
......
...@@ -18,7 +18,7 @@ namespace tether { ...@@ -18,7 +18,7 @@ namespace tether {
// Note that this upper limit on concurrent advertisements is imposed due to a // Note that this upper limit on concurrent advertisements is imposed due to a
// hardware limit of advertisements (many devices have <10 total advertisement // hardware limit of advertisements (many devices have <10 total advertisement
// slots). // slots).
extern const int kMaxConcurrentAdvertisements; extern const uint8_t kMaxConcurrentAdvertisements;
// The service UUID used for BLE advertisements. // The service UUID used for BLE advertisements.
extern const char kAdvertisingServiceUuid[]; extern const char kAdvertisingServiceUuid[];
......
This diff is collapsed.
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_COMPONENTS_BLE_SCANNER_H_
#define CHROMEOS_COMPONENTS_BLE_SCANNER_H_
#include <map>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chromeos/components/tether/local_device_data_provider.h"
#include "components/cryptauth/eid_generator.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
namespace device {
class BluetoothDevice;
class BluetoothDiscoverySession;
}
namespace chromeos {
namespace tether {
class BleScanner : public device::BluetoothAdapter::Observer {
public:
class Observer {
public:
virtual void OnReceivedAdvertisementFromDevice(
const device::BluetoothDevice* bluetooth_device,
cryptauth::RemoteDevice remote_device) = 0;
};
BleScanner(const LocalDeviceDataProvider* local_device_data_provider);
~BleScanner() override;
bool RegisterScanFilterForDevice(
const cryptauth::RemoteDevice& remote_device);
bool UnregisterScanFilterForDevice(
const cryptauth::RemoteDevice& remote_device);
bool IsDeviceRegistered(const std::string& device_id);
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// device::BluetoothAdapter::Observer
void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
bool powered) override;
void DeviceAdded(device::BluetoothAdapter* adapter,
device::BluetoothDevice* bluetooth_device) override;
void DeviceChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* bluetooth_device) override;
private:
friend class BleScannerTest;
class Delegate {
public:
virtual ~Delegate() {}
virtual bool IsBluetoothAdapterAvailable() const = 0;
virtual void GetAdapter(
const device::BluetoothAdapterFactory::AdapterCallback& callback) = 0;
virtual const std::vector<uint8_t>* GetServiceDataForUUID(
const device::BluetoothUUID& service_uuid,
device::BluetoothDevice* bluetooth_device) = 0;
};
class DelegateImpl : public Delegate {
public:
DelegateImpl();
~DelegateImpl() override;
bool IsBluetoothAdapterAvailable() const override;
void GetAdapter(const device::BluetoothAdapterFactory::AdapterCallback&
callback) override;
const std::vector<uint8_t>* GetServiceDataForUUID(
const device::BluetoothUUID& service_uuid,
device::BluetoothDevice* bluetooth_device) override;
};
BleScanner(std::unique_ptr<Delegate> delegate,
const cryptauth::EidGenerator* eid_generator,
const LocalDeviceDataProvider* local_device_data_provider);
void UpdateDiscoveryStatus();
void InitializeBluetoothAdapter();
void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter);
void StartDiscoverySession();
void OnDiscoverySessionStarted(
std::unique_ptr<device::BluetoothDiscoverySession> discovery_session);
void OnStartDiscoverySessionError();
void StopDiscoverySession();
void HandleDeviceUpdated(device::BluetoothDevice* bluetooth_device);
void CheckForMatchingScanFilters(device::BluetoothDevice* bluetooth_device,
std::string& service_data);
std::unique_ptr<Delegate> delegate_;
// |eid_generator_| and |local_device_data_provider_| are not owned by this
// instance and must outlive it.
const cryptauth::EidGenerator* eid_generator_;
const LocalDeviceDataProvider* local_device_data_provider_;
bool is_initializing_adapter_;
scoped_refptr<device::BluetoothAdapter> adapter_;
bool is_initializing_discovery_session_;
std::unique_ptr<device::BluetoothDiscoverySession> discovery_session_;
std::vector<cryptauth::RemoteDevice> registered_remote_devices_;
base::ObserverList<Observer> observer_list_;
base::WeakPtrFactory<BleScanner> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BleScanner);
};
} // namespace tether
} // namespace chromeos
#endif // CHROMEOS_COMPONENTS_BLE_SCANNER_H_
This diff is collapsed.
...@@ -36,7 +36,7 @@ class LocalDeviceDataProvider { ...@@ -36,7 +36,7 @@ class LocalDeviceDataProvider {
// Fetches the public key and/or the beacon seeds for the local device. // Fetches the public key and/or the beacon seeds for the local device.
// Returns whether the operation succeeded. If |nullptr| is passed as a // Returns whether the operation succeeded. If |nullptr| is passed as a
// parameter, the associated data will not be fetched. // parameter, the associated data will not be fetched.
bool GetLocalDeviceData( virtual bool GetLocalDeviceData(
std::string* public_key_out, std::string* public_key_out,
std::vector<cryptauth::BeaconSeed>* beacon_seeds_out) const; std::vector<cryptauth::BeaconSeed>* beacon_seeds_out) const;
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/components/tether/mock_local_device_data_provider.h"
#include "components/cryptauth/cryptauth_device_manager.h"
#include "components/cryptauth/cryptauth_enrollment_manager.h"
#include "components/cryptauth/proto/cryptauth_api.pb.h"
namespace chromeos {
namespace tether {
MockLocalDeviceDataProvider::MockLocalDeviceDataProvider()
: LocalDeviceDataProvider(nullptr, nullptr) {}
MockLocalDeviceDataProvider::~MockLocalDeviceDataProvider() {}
void MockLocalDeviceDataProvider::SetPublicKey(
std::unique_ptr<std::string> public_key) {
if (public_key) {
public_key_ = std::move(public_key);
} else {
public_key_.reset();
}
}
void MockLocalDeviceDataProvider::SetBeaconSeeds(
std::unique_ptr<std::vector<cryptauth::BeaconSeed>> beacon_seeds) {
if (beacon_seeds) {
beacon_seeds_ = std::move(beacon_seeds);
} else {
beacon_seeds_.reset();
}
}
bool MockLocalDeviceDataProvider::GetLocalDeviceData(
std::string* public_key_out,
std::vector<cryptauth::BeaconSeed>* beacon_seeds_out) const {
if (public_key_ && beacon_seeds_) {
if (public_key_out) {
*public_key_out = *public_key_;
}
if (beacon_seeds_out) {
*beacon_seeds_out = *beacon_seeds_;
}
return true;
}
return false;
}
} // namespace tether
} // namespace cryptauth
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_COMPONENTS_TETHER_MOCK_LOCAL_DEVICE_DATA_PROVIDER_H
#define CHROMEOS_COMPONENTS_TETHER_MOCK_LOCAL_DEVICE_DATA_PROVIDER_H
#include <memory>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "chromeos/components/tether/local_device_data_provider.h"
namespace cryptauth {
class BeaconSeed;
}
namespace chromeos {
namespace tether {
// Test double for LocalDeviceDataProvider.
class MockLocalDeviceDataProvider : public LocalDeviceDataProvider {
public:
MockLocalDeviceDataProvider();
~MockLocalDeviceDataProvider() override;
void SetPublicKey(std::unique_ptr<std::string> public_key);
void SetBeaconSeeds(
std::unique_ptr<std::vector<cryptauth::BeaconSeed>> beacon_seeds);
// LocalDeviceDataProvider:
bool GetLocalDeviceData(
std::string* public_key_out,
std::vector<cryptauth::BeaconSeed>* beacon_seeds_out) const override;
private:
std::unique_ptr<std::string> public_key_;
std::unique_ptr<std::vector<cryptauth::BeaconSeed>> beacon_seeds_;
DISALLOW_COPY_AND_ASSIGN(MockLocalDeviceDataProvider);
};
} // namespace tether
} // namespace chromeos
#endif // CHROMEOS_COMPONENTS_TETHER_MOCK_LOCAL_DEVICE_DATA_PROVIDER_H
...@@ -11,7 +11,8 @@ namespace cryptauth { ...@@ -11,7 +11,8 @@ namespace cryptauth {
MockEidGenerator::MockEidGenerator() : background_scan_filter_(nullptr), MockEidGenerator::MockEidGenerator() : background_scan_filter_(nullptr),
advertisement_(nullptr), advertisement_(nullptr),
possible_advertisements_(nullptr), possible_advertisements_(nullptr),
identified_device_(nullptr) {} identified_device_(nullptr),
num_identify_calls_(0) {}
MockEidGenerator::~MockEidGenerator() {} MockEidGenerator::~MockEidGenerator() {}
...@@ -62,6 +63,11 @@ RemoteDevice const* MockEidGenerator::IdentifyRemoteDeviceByAdvertisement( ...@@ -62,6 +63,11 @@ RemoteDevice const* MockEidGenerator::IdentifyRemoteDeviceByAdvertisement(
const std::string& advertisement_service_data, const std::string& advertisement_service_data,
const std::vector<RemoteDevice>& device_list, const std::vector<RemoteDevice>& device_list,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const { const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
// Increment num_identify_calls_. Since this overrides a const method, some
// hacking is needed to modify the num_identify_calls_ instance variable.
int* num_identify_calls_ptr = const_cast<int*>(&num_identify_calls_);
*num_identify_calls_ptr = *num_identify_calls_ptr + 1;
return identified_device_; return identified_device_;
} }
......
...@@ -60,11 +60,17 @@ class MockEidGenerator : public EidGenerator { ...@@ -60,11 +60,17 @@ class MockEidGenerator : public EidGenerator {
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const std::vector<BeaconSeed>& scanning_device_beacon_seeds)
const override; const override;
int num_identify_calls() {
return num_identify_calls_;
}
private: private:
std::unique_ptr<EidData> background_scan_filter_; std::unique_ptr<EidData> background_scan_filter_;
std::unique_ptr<DataWithTimestamp> advertisement_; std::unique_ptr<DataWithTimestamp> advertisement_;
std::unique_ptr<std::vector<std::string>> possible_advertisements_; std::unique_ptr<std::vector<std::string>> possible_advertisements_;
const RemoteDevice* identified_device_; const RemoteDevice* identified_device_;
int num_identify_calls_;
}; };
} // namespace cryptauth } // namespace cryptauth
......
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