Commit 8fb5cdf0 authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS PhoneHub] Set bluetooth_public_address field during DeviceSync

When the kPhoneHub flag is enabled, we now set the
bluetooth_public_address field of the encrypted metadata during
DeviceSync v2 attempts.

This CL:
(1) Adds the SyncedBluetoothAddressTracker class, which fetches the
    Bluetooth address using the BluetoothAdapter class.
(2) Integrates this class with the rest of the DeviceSync flow.
(3) Triggers a DeviceSync whenever the address has changed (e.g., if a
    user plugs in a USB Bluetooth adapter).
(4) Preserves existing functionality (i.e., no synced Bluetooth address)
    when the flag is disabled.

Bug: 1106937
Change-Id: If967f08913f495410323032094fd1f7312061057
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2342199Reviewed-by: default avatarJosh Nohle <nohle@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796606}
parent aed22775
...@@ -137,6 +137,9 @@ static_library("device_sync") { ...@@ -137,6 +137,9 @@ static_library("device_sync") {
"sync_scheduler.h", "sync_scheduler.h",
"sync_scheduler_impl.cc", "sync_scheduler_impl.cc",
"sync_scheduler_impl.h", "sync_scheduler_impl.h",
"synced_bluetooth_address_tracker.h",
"synced_bluetooth_address_tracker_impl.cc",
"synced_bluetooth_address_tracker_impl.h",
"value_string_encoding.cc", "value_string_encoding.cc",
"value_string_encoding.h", "value_string_encoding.h",
] ]
...@@ -162,6 +165,7 @@ static_library("device_sync") { ...@@ -162,6 +165,7 @@ static_library("device_sync") {
"//chromeos/services/device_sync/public/mojom", "//chromeos/services/device_sync/public/mojom",
"//components/gcm_driver", "//components/gcm_driver",
"//components/prefs", "//components/prefs",
"//device/bluetooth",
"//net", "//net",
"//third_party/securemessage/proto", "//third_party/securemessage/proto",
] ]
...@@ -222,6 +226,8 @@ static_library("test_support") { ...@@ -222,6 +226,8 @@ static_library("test_support") {
"fake_remote_device_v2_loader.h", "fake_remote_device_v2_loader.h",
"fake_software_feature_manager.cc", "fake_software_feature_manager.cc",
"fake_software_feature_manager.h", "fake_software_feature_manager.h",
"fake_synced_bluetooth_address_tracker.cc",
"fake_synced_bluetooth_address_tracker.h",
"mock_cryptauth_client.cc", "mock_cryptauth_client.cc",
"mock_cryptauth_client.h", "mock_cryptauth_client.h",
"mock_sync_scheduler.cc", "mock_sync_scheduler.cc",
...@@ -277,6 +283,7 @@ source_set("unit_tests") { ...@@ -277,6 +283,7 @@ source_set("unit_tests") {
"remote_device_v2_loader_impl_unittest.cc", "remote_device_v2_loader_impl_unittest.cc",
"software_feature_manager_impl_unittest.cc", "software_feature_manager_impl_unittest.cc",
"sync_scheduler_impl_unittest.cc", "sync_scheduler_impl_unittest.cc",
"synced_bluetooth_address_tracker_impl_unittest.cc",
] ]
deps = [ deps = [
...@@ -300,6 +307,7 @@ source_set("unit_tests") { ...@@ -300,6 +307,7 @@ source_set("unit_tests") {
"//components/gcm_driver:test_support", "//components/gcm_driver:test_support",
"//components/prefs:test_support", "//components/prefs:test_support",
"//components/signin/public/identity_manager:test_support", "//components/signin/public/identity_manager:test_support",
"//device/bluetooth:mocks",
"//net/traffic_annotation:test_support", "//net/traffic_annotation:test_support",
"//services/network:test_support", "//services/network:test_support",
"//testing/gmock", "//testing/gmock",
......
...@@ -3,6 +3,7 @@ include_rules = [ ...@@ -3,6 +3,7 @@ include_rules = [
"+components/proximity_auth/logging", "+components/proximity_auth/logging",
"+components/signin/public", "+components/signin/public",
"+components/version_info", "+components/version_info",
"+device/bluetooth",
"+google_apis/gaia", "+google_apis/gaia",
"+mojo/public/cpp", "+mojo/public/cpp",
"+services/network/public", "+services/network/public",
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "chromeos/services/device_sync/cryptauth_task_metrics_logger.h" #include "chromeos/services/device_sync/cryptauth_task_metrics_logger.h"
#include "chromeos/services/device_sync/proto/cryptauth_client_app_metadata.pb.h" #include "chromeos/services/device_sync/proto/cryptauth_client_app_metadata.pb.h"
#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h" #include "chromeos/services/device_sync/proto/cryptauth_common.pb.h"
#include "chromeos/services/device_sync/synced_bluetooth_address_tracker.h"
#include "chromeos/services/device_sync/value_string_encoding.h" #include "chromeos/services/device_sync/value_string_encoding.h"
namespace chromeos { namespace chromeos {
...@@ -76,17 +77,18 @@ CryptAuthDeviceSyncerImpl::Factory::Create( ...@@ -76,17 +77,18 @@ CryptAuthDeviceSyncerImpl::Factory::Create(
CryptAuthDeviceRegistry* device_registry, CryptAuthDeviceRegistry* device_registry,
CryptAuthKeyRegistry* key_registry, CryptAuthKeyRegistry* key_registry,
CryptAuthClientFactory* client_factory, CryptAuthClientFactory* client_factory,
SyncedBluetoothAddressTracker* synced_bluetooth_address_tracker,
PrefService* pref_service, PrefService* pref_service,
std::unique_ptr<base::OneShotTimer> timer) { std::unique_ptr<base::OneShotTimer> timer) {
if (test_factory_) { if (test_factory_) {
return test_factory_->CreateInstance(device_registry, key_registry, return test_factory_->CreateInstance(
client_factory, pref_service, device_registry, key_registry, client_factory,
std::move(timer)); synced_bluetooth_address_tracker, pref_service, std::move(timer));
} }
return base::WrapUnique(new CryptAuthDeviceSyncerImpl( return base::WrapUnique(new CryptAuthDeviceSyncerImpl(
device_registry, key_registry, client_factory, pref_service, device_registry, key_registry, client_factory,
std::move(timer))); synced_bluetooth_address_tracker, pref_service, std::move(timer)));
} }
// static // static
...@@ -101,11 +103,13 @@ CryptAuthDeviceSyncerImpl::CryptAuthDeviceSyncerImpl( ...@@ -101,11 +103,13 @@ CryptAuthDeviceSyncerImpl::CryptAuthDeviceSyncerImpl(
CryptAuthDeviceRegistry* device_registry, CryptAuthDeviceRegistry* device_registry,
CryptAuthKeyRegistry* key_registry, CryptAuthKeyRegistry* key_registry,
CryptAuthClientFactory* client_factory, CryptAuthClientFactory* client_factory,
SyncedBluetoothAddressTracker* synced_bluetooth_address_tracker,
PrefService* pref_service, PrefService* pref_service,
std::unique_ptr<base::OneShotTimer> timer) std::unique_ptr<base::OneShotTimer> timer)
: device_registry_(device_registry), : device_registry_(device_registry),
key_registry_(key_registry), key_registry_(key_registry),
client_factory_(client_factory), client_factory_(client_factory),
synced_bluetooth_address_tracker_(synced_bluetooth_address_tracker),
pref_service_(pref_service), pref_service_(pref_service),
timer_(std::move(timer)) { timer_(std::move(timer)) {
DCHECK(device_registry); DCHECK(device_registry);
...@@ -126,9 +130,10 @@ base::Optional<base::TimeDelta> CryptAuthDeviceSyncerImpl::GetTimeoutForState( ...@@ -126,9 +130,10 @@ base::Optional<base::TimeDelta> CryptAuthDeviceSyncerImpl::GetTimeoutForState(
default: default:
// Signifies that there should not be a timeout. // Signifies that there should not be a timeout.
// Note: CryptAuthMetadataSyncerImpl, CryptAuthFeatureStatusGetterImpl, // Note: CryptAuthMetadataSyncerImpl, CryptAuthFeatureStatusGetterImpl,
// and CryptAuthGroupPrivateKeySharerImpl guarantee that the callbacks // CryptAuthGroupPrivateKeySharerImpl, and BluetoothAdapter guarantee that
// passed to their public methods are always invoke; in other words, these // the callbacks passed to their public methods are always invoke; in
// implementations handle their relevant timeouts internally. // other words, these implementations handle their relevant timeouts
// internally.
return base::nullopt; return base::nullopt;
} }
} }
...@@ -218,6 +223,9 @@ void CryptAuthDeviceSyncerImpl::OnTimeout() { ...@@ -218,6 +223,9 @@ void CryptAuthDeviceSyncerImpl::OnTimeout() {
void CryptAuthDeviceSyncerImpl::AttemptNextStep() { void CryptAuthDeviceSyncerImpl::AttemptNextStep() {
switch (state_) { switch (state_) {
case State::kNotStarted: case State::kNotStarted:
GetBluetoothAddress();
return;
case State::kWaitingForBluetoothAddress:
SyncMetadata(); SyncMetadata();
return; return;
case State::kWaitingForMetadataSync: case State::kWaitingForMetadataSync:
...@@ -247,6 +255,26 @@ void CryptAuthDeviceSyncerImpl::AttemptNextStep() { ...@@ -247,6 +255,26 @@ void CryptAuthDeviceSyncerImpl::AttemptNextStep() {
} }
} }
void CryptAuthDeviceSyncerImpl::GetBluetoothAddress() {
DCHECK_EQ(State::kNotStarted, state_);
SetState(State::kWaitingForBluetoothAddress);
synced_bluetooth_address_tracker_->GetBluetoothAddress(
base::BindOnce(&CryptAuthDeviceSyncerImpl::OnBluetoothAddress,
weak_ptr_factory_.GetWeakPtr()));
}
void CryptAuthDeviceSyncerImpl::OnBluetoothAddress(
const std::string& bluetooth_address) {
DCHECK_EQ(State::kWaitingForBluetoothAddress, state_);
if (!bluetooth_address.empty()) {
local_better_together_device_metadata_.set_bluetooth_public_address(
bluetooth_address);
}
AttemptNextStep();
}
void CryptAuthDeviceSyncerImpl::SyncMetadata() { void CryptAuthDeviceSyncerImpl::SyncMetadata() {
SetState(State::kWaitingForMetadataSync); SetState(State::kWaitingForMetadataSync);
...@@ -681,6 +709,13 @@ void CryptAuthDeviceSyncerImpl::FinishAttempt( ...@@ -681,6 +709,13 @@ void CryptAuthDeviceSyncerImpl::FinishAttempt(
encryptor_.reset(); encryptor_.reset();
group_private_key_sharer_.reset(); group_private_key_sharer_.reset();
CryptAuthDeviceSyncResult::ResultType result_type =
CryptAuthDeviceSyncResult::GetResultType(result_code);
if (result_type == CryptAuthDeviceSyncResult::ResultType::kSuccess) {
synced_bluetooth_address_tracker_->SetLastSyncedBluetoothAddress(
local_better_together_device_metadata_.bluetooth_public_address());
}
bool did_device_registry_change = bool did_device_registry_change =
new_device_registry_map_ && new_device_registry_map_ &&
device_registry_->SetRegistry(*new_device_registry_map_); device_registry_->SetRegistry(*new_device_registry_map_);
...@@ -695,6 +730,9 @@ std::ostream& operator<<(std::ostream& stream, ...@@ -695,6 +730,9 @@ std::ostream& operator<<(std::ostream& stream,
case CryptAuthDeviceSyncerImpl::State::kNotStarted: case CryptAuthDeviceSyncerImpl::State::kNotStarted:
stream << "[DeviceSyncer state: Not started]"; stream << "[DeviceSyncer state: Not started]";
break; break;
case CryptAuthDeviceSyncerImpl::State::kWaitingForBluetoothAddress:
stream << "[DeviceSyncer state: Waiting for Bluetooth address]";
break;
case CryptAuthDeviceSyncerImpl::State::kWaitingForMetadataSync: case CryptAuthDeviceSyncerImpl::State::kWaitingForMetadataSync:
stream << "[DeviceSyncer state: Waiting for metadata sync]"; stream << "[DeviceSyncer state: Waiting for metadata sync]";
break; break;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
...@@ -43,6 +44,7 @@ namespace device_sync { ...@@ -43,6 +44,7 @@ namespace device_sync {
class CryptAuthClient; class CryptAuthClient;
class CryptAuthClientFactory; class CryptAuthClientFactory;
class CryptAuthKeyRegistry; class CryptAuthKeyRegistry;
class SyncedBluetoothAddressTracker;
// An implementation of CryptAuthDeviceSyncer, using instances of // An implementation of CryptAuthDeviceSyncer, using instances of
// CryptAuthClient to make the API calls to CryptAuth. This implementation // CryptAuthClient to make the API calls to CryptAuth. This implementation
...@@ -64,6 +66,7 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer { ...@@ -64,6 +66,7 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer {
CryptAuthDeviceRegistry* device_registry, CryptAuthDeviceRegistry* device_registry,
CryptAuthKeyRegistry* key_registry, CryptAuthKeyRegistry* key_registry,
CryptAuthClientFactory* client_factory, CryptAuthClientFactory* client_factory,
SyncedBluetoothAddressTracker* synced_bluetooth_address_tracker,
PrefService* pref_service, PrefService* pref_service,
std::unique_ptr<base::OneShotTimer> timer = std::unique_ptr<base::OneShotTimer> timer =
std::make_unique<base::OneShotTimer>()); std::make_unique<base::OneShotTimer>());
...@@ -75,6 +78,7 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer { ...@@ -75,6 +78,7 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer {
CryptAuthDeviceRegistry* device_registry, CryptAuthDeviceRegistry* device_registry,
CryptAuthKeyRegistry* key_registry, CryptAuthKeyRegistry* key_registry,
CryptAuthClientFactory* client_factory, CryptAuthClientFactory* client_factory,
SyncedBluetoothAddressTracker* synced_bluetooth_address_tracker,
PrefService* pref_service, PrefService* pref_service,
std::unique_ptr<base::OneShotTimer> timer) = 0; std::unique_ptr<base::OneShotTimer> timer) = 0;
...@@ -87,6 +91,7 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer { ...@@ -87,6 +91,7 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer {
private: private:
enum class State { enum class State {
kNotStarted, kNotStarted,
kWaitingForBluetoothAddress,
kWaitingForMetadataSync, kWaitingForMetadataSync,
kWaitingForFeatureStatuses, kWaitingForFeatureStatuses,
kWaitingForEncryptedGroupPrivateKeyProcessing, kWaitingForEncryptedGroupPrivateKeyProcessing,
...@@ -107,12 +112,16 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer { ...@@ -107,12 +112,16 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer {
// and it will read the user key pair and the key used for decrypting the // and it will read the user key pair and the key used for decrypting the
// group private key. // group private key.
// |client_factory|: Creates CryptAuthClient instances for making API calls. // |client_factory|: Creates CryptAuthClient instances for making API calls.
// |synced_bluetooth_address_tracker|: Used to fetch Bluetooth address and
// track address used for successful syncs.
// |timer|: Handles timeouts for asynchronous operations. // |timer|: Handles timeouts for asynchronous operations.
CryptAuthDeviceSyncerImpl(CryptAuthDeviceRegistry* device_registry, CryptAuthDeviceSyncerImpl(
CryptAuthKeyRegistry* key_registry, CryptAuthDeviceRegistry* device_registry,
CryptAuthClientFactory* client_factory, CryptAuthKeyRegistry* key_registry,
PrefService* pref_service, CryptAuthClientFactory* client_factory,
std::unique_ptr<base::OneShotTimer> timer); SyncedBluetoothAddressTracker* synced_bluetooth_address_tracker,
PrefService* pref_service,
std::unique_ptr<base::OneShotTimer> timer);
// CryptAuthDeviceSyncer: // CryptAuthDeviceSyncer:
void OnAttemptStarted( void OnAttemptStarted(
...@@ -125,6 +134,9 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer { ...@@ -125,6 +134,9 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer {
// Controls the logical flow of the class. // Controls the logical flow of the class.
void AttemptNextStep(); void AttemptNextStep();
void GetBluetoothAddress();
void OnBluetoothAddress(const std::string& bluetooth_address);
void SyncMetadata(); void SyncMetadata();
void OnSyncMetadataFinished( void OnSyncMetadataFinished(
const CryptAuthMetadataSyncer::IdToDeviceMetadataPacketMap& const CryptAuthMetadataSyncer::IdToDeviceMetadataPacketMap&
...@@ -208,9 +220,12 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer { ...@@ -208,9 +220,12 @@ class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer {
CryptAuthDeviceRegistry* device_registry_ = nullptr; CryptAuthDeviceRegistry* device_registry_ = nullptr;
CryptAuthKeyRegistry* key_registry_ = nullptr; CryptAuthKeyRegistry* key_registry_ = nullptr;
CryptAuthClientFactory* client_factory_ = nullptr; CryptAuthClientFactory* client_factory_ = nullptr;
SyncedBluetoothAddressTracker* synced_bluetooth_address_tracker_ = nullptr;
PrefService* pref_service_ = nullptr; PrefService* pref_service_ = nullptr;
std::unique_ptr<base::OneShotTimer> timer_; std::unique_ptr<base::OneShotTimer> timer_;
base::WeakPtrFactory<CryptAuthDeviceSyncerImpl> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(CryptAuthDeviceSyncerImpl); DISALLOW_COPY_AND_ASSIGN(CryptAuthDeviceSyncerImpl);
}; };
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "chromeos/services/device_sync/fake_cryptauth_group_private_key_sharer.h" #include "chromeos/services/device_sync/fake_cryptauth_group_private_key_sharer.h"
#include "chromeos/services/device_sync/fake_cryptauth_metadata_syncer.h" #include "chromeos/services/device_sync/fake_cryptauth_metadata_syncer.h"
#include "chromeos/services/device_sync/fake_ecies_encryption.h" #include "chromeos/services/device_sync/fake_ecies_encryption.h"
#include "chromeos/services/device_sync/fake_synced_bluetooth_address_tracker.h"
#include "chromeos/services/device_sync/mock_cryptauth_client.h" #include "chromeos/services/device_sync/mock_cryptauth_client.h"
#include "chromeos/services/device_sync/network_request_error.h" #include "chromeos/services/device_sync/network_request_error.h"
#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h" #include "chromeos/services/device_sync/proto/cryptauth_common.pb.h"
...@@ -112,7 +113,9 @@ class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test { ...@@ -112,7 +113,9 @@ class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test {
fake_cryptauth_feature_status_getter_factory_( fake_cryptauth_feature_status_getter_factory_(
std::make_unique<FakeCryptAuthFeatureStatusGetterFactory>()), std::make_unique<FakeCryptAuthFeatureStatusGetterFactory>()),
fake_cryptauth_group_private_key_sharer_factory_( fake_cryptauth_group_private_key_sharer_factory_(
std::make_unique<FakeCryptAuthGroupPrivateKeySharerFactory>()) { std::make_unique<FakeCryptAuthGroupPrivateKeySharerFactory>()),
fake_synced_bluetooth_address_tracker_(
std::make_unique<FakeSyncedBluetoothAddressTracker>()) {
CryptAuthKeyRegistryImpl::RegisterPrefs(pref_service_.registry()); CryptAuthKeyRegistryImpl::RegisterPrefs(pref_service_.registry());
key_registry_ = CryptAuthKeyRegistryImpl::Factory::Create(&pref_service_); key_registry_ = CryptAuthKeyRegistryImpl::Factory::Create(&pref_service_);
CryptAuthDeviceRegistryImpl::RegisterPrefs(pref_service_.registry()); CryptAuthDeviceRegistryImpl::RegisterPrefs(pref_service_.registry());
...@@ -138,7 +141,8 @@ class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test { ...@@ -138,7 +141,8 @@ class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test {
syncer_ = CryptAuthDeviceSyncerImpl::Factory::Create( syncer_ = CryptAuthDeviceSyncerImpl::Factory::Create(
device_registry_.get(), key_registry_.get(), client_factory_.get(), device_registry_.get(), key_registry_.get(), client_factory_.get(),
&pref_service_, std::move(mock_timer)); fake_synced_bluetooth_address_tracker_.get(), &pref_service_,
std::move(mock_timer));
std::string local_user_public_key = std::string local_user_public_key =
GetLocalDeviceForTest().better_together_device_metadata->public_key(); GetLocalDeviceForTest().better_together_device_metadata->public_key();
...@@ -371,6 +375,16 @@ class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test { ...@@ -371,6 +375,16 @@ class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test {
ASSERT_TRUE(device_sync_result_); ASSERT_TRUE(device_sync_result_);
EXPECT_EQ(expected_result, *device_sync_result_); EXPECT_EQ(expected_result, *device_sync_result_);
if (expected_result.IsSuccess()) {
EXPECT_EQ(kDefaultLocalDeviceBluetoothAddress,
fake_synced_bluetooth_address_tracker_
->last_synced_bluetooth_address());
} else {
EXPECT_TRUE(fake_synced_bluetooth_address_tracker_
->last_synced_bluetooth_address()
.empty());
}
CryptAuthDeviceRegistry::InstanceIdToDeviceMap expected_registry; CryptAuthDeviceRegistry::InstanceIdToDeviceMap expected_registry;
for (const CryptAuthDevice& device : expected_devices_in_registry) { for (const CryptAuthDevice& device : expected_devices_in_registry) {
expected_registry.insert_or_assign(device.instance_id(), device); expected_registry.insert_or_assign(device.instance_id(), device);
...@@ -416,6 +430,8 @@ class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test { ...@@ -416,6 +430,8 @@ class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test {
TestingPrefServiceSimple pref_service_; TestingPrefServiceSimple pref_service_;
std::unique_ptr<CryptAuthKeyRegistry> key_registry_; std::unique_ptr<CryptAuthKeyRegistry> key_registry_;
std::unique_ptr<CryptAuthDeviceRegistry> device_registry_; std::unique_ptr<CryptAuthDeviceRegistry> device_registry_;
std::unique_ptr<FakeSyncedBluetoothAddressTracker>
fake_synced_bluetooth_address_tracker_;
base::MockOneShotTimer* timer_; base::MockOneShotTimer* timer_;
base::Optional<CryptAuthDeviceSyncResult> device_sync_result_; base::Optional<CryptAuthDeviceSyncResult> device_sync_result_;
......
...@@ -9,10 +9,12 @@ ...@@ -9,10 +9,12 @@
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "chromeos/components/multidevice/logging/logging.h" #include "chromeos/components/multidevice/logging/logging.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/device_sync/cryptauth_client.h" #include "chromeos/services/device_sync/cryptauth_client.h"
#include "chromeos/services/device_sync/cryptauth_device_syncer_impl.h" #include "chromeos/services/device_sync/cryptauth_device_syncer_impl.h"
#include "chromeos/services/device_sync/cryptauth_key_registry.h" #include "chromeos/services/device_sync/cryptauth_key_registry.h"
#include "chromeos/services/device_sync/proto/cryptauth_logging.h" #include "chromeos/services/device_sync/proto/cryptauth_logging.h"
#include "chromeos/services/device_sync/synced_bluetooth_address_tracker_impl.h"
namespace chromeos { namespace chromeos {
...@@ -73,7 +75,10 @@ CryptAuthV2DeviceManagerImpl::CryptAuthV2DeviceManagerImpl( ...@@ -73,7 +75,10 @@ CryptAuthV2DeviceManagerImpl::CryptAuthV2DeviceManagerImpl(
CryptAuthGCMManager* gcm_manager, CryptAuthGCMManager* gcm_manager,
CryptAuthScheduler* scheduler, CryptAuthScheduler* scheduler,
PrefService* pref_service) PrefService* pref_service)
: client_app_metadata_(client_app_metadata), : synced_bluetooth_address_tracker_(
SyncedBluetoothAddressTrackerImpl::Factory::Create(scheduler,
pref_service)),
client_app_metadata_(client_app_metadata),
device_registry_(device_registry), device_registry_(device_registry),
key_registry_(key_registry), key_registry_(key_registry),
client_factory_(client_factory), client_factory_(client_factory),
...@@ -138,7 +143,8 @@ void CryptAuthV2DeviceManagerImpl::OnDeviceSyncRequested( ...@@ -138,7 +143,8 @@ void CryptAuthV2DeviceManagerImpl::OnDeviceSyncRequested(
PA_LOG(VERBOSE) << "Starting CryptAuth v2 DeviceSync."; PA_LOG(VERBOSE) << "Starting CryptAuth v2 DeviceSync.";
device_syncer_ = CryptAuthDeviceSyncerImpl::Factory::Create( device_syncer_ = CryptAuthDeviceSyncerImpl::Factory::Create(
device_registry_, key_registry_, client_factory_, pref_service_); device_registry_, key_registry_, client_factory_,
synced_bluetooth_address_tracker_.get(), pref_service_);
device_syncer_->Sync( device_syncer_->Sync(
*current_client_metadata_, client_app_metadata_, *current_client_metadata_, client_app_metadata_,
base::BindOnce(&CryptAuthV2DeviceManagerImpl::OnDeviceSyncFinished, base::BindOnce(&CryptAuthV2DeviceManagerImpl::OnDeviceSyncFinished,
......
...@@ -30,6 +30,7 @@ namespace device_sync { ...@@ -30,6 +30,7 @@ namespace device_sync {
class CryptAuthClientFactory; class CryptAuthClientFactory;
class CryptAuthDeviceSyncer; class CryptAuthDeviceSyncer;
class CryptAuthKeyRegistry; class CryptAuthKeyRegistry;
class SyncedBluetoothAddressTracker;
// Implementation of CryptAuthV2DeviceManager that considers three sources of // Implementation of CryptAuthV2DeviceManager that considers three sources of
// DeviceSync requests: // DeviceSync requests:
...@@ -107,6 +108,8 @@ class CryptAuthV2DeviceManagerImpl ...@@ -107,6 +108,8 @@ class CryptAuthV2DeviceManagerImpl
void OnDeviceSyncFinished(CryptAuthDeviceSyncResult device_sync_result); void OnDeviceSyncFinished(CryptAuthDeviceSyncResult device_sync_result);
base::Optional<cryptauthv2::ClientMetadata> current_client_metadata_; base::Optional<cryptauthv2::ClientMetadata> current_client_metadata_;
std::unique_ptr<SyncedBluetoothAddressTracker>
synced_bluetooth_address_tracker_;
std::unique_ptr<CryptAuthDeviceSyncer> device_syncer_; std::unique_ptr<CryptAuthDeviceSyncer> device_syncer_;
cryptauthv2::ClientAppMetadata client_app_metadata_; cryptauthv2::ClientAppMetadata client_app_metadata_;
......
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
#include "base/optional.h" #include "base/optional.h"
#include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "chromeos/services/device_sync/cryptauth_device_registry_impl.h" #include "chromeos/services/device_sync/cryptauth_device_registry_impl.h"
#include "chromeos/services/device_sync/cryptauth_device_syncer_impl.h" #include "chromeos/services/device_sync/cryptauth_device_syncer_impl.h"
#include "chromeos/services/device_sync/cryptauth_key_registry_impl.h" #include "chromeos/services/device_sync/cryptauth_key_registry_impl.h"
#include "chromeos/services/device_sync/fake_cryptauth_device_syncer.h" #include "chromeos/services/device_sync/fake_cryptauth_device_syncer.h"
#include "chromeos/services/device_sync/fake_cryptauth_gcm_manager.h" #include "chromeos/services/device_sync/fake_cryptauth_gcm_manager.h"
#include "chromeos/services/device_sync/fake_cryptauth_scheduler.h" #include "chromeos/services/device_sync/fake_cryptauth_scheduler.h"
#include "chromeos/services/device_sync/fake_synced_bluetooth_address_tracker.h"
#include "chromeos/services/device_sync/mock_cryptauth_client.h" #include "chromeos/services/device_sync/mock_cryptauth_client.h"
#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h" #include "chromeos/services/device_sync/proto/cryptauth_common.pb.h"
#include "chromeos/services/device_sync/proto/cryptauth_v2_test_util.h" #include "chromeos/services/device_sync/proto/cryptauth_v2_test_util.h"
...@@ -75,6 +77,9 @@ class DeviceSyncCryptAuthV2DeviceManagerImplTest ...@@ -75,6 +77,9 @@ class DeviceSyncCryptAuthV2DeviceManagerImplTest
std::make_unique<FakeCryptAuthDeviceSyncerFactory>(); std::make_unique<FakeCryptAuthDeviceSyncerFactory>();
CryptAuthDeviceSyncerImpl::Factory::SetFactoryForTesting( CryptAuthDeviceSyncerImpl::Factory::SetFactoryForTesting(
fake_device_syncer_factory_.get()); fake_device_syncer_factory_.get());
SyncedBluetoothAddressTrackerImpl::Factory::SetFactoryForTesting(
&fake_synced_bluetooth_address_tracker_factory_);
} }
// testing::Test: // testing::Test:
...@@ -279,6 +284,8 @@ class DeviceSyncCryptAuthV2DeviceManagerImplTest ...@@ -279,6 +284,8 @@ class DeviceSyncCryptAuthV2DeviceManagerImplTest
device_registry_changed_count); device_registry_changed_count);
} }
base::test::TaskEnvironment task_environment_;
std::vector<cryptauthv2::ClientMetadata> expected_client_metadata_list_; std::vector<cryptauthv2::ClientMetadata> expected_client_metadata_list_;
std::vector<CryptAuthDeviceSyncResult> expected_device_sync_results_; std::vector<CryptAuthDeviceSyncResult> expected_device_sync_results_;
...@@ -293,6 +300,8 @@ class DeviceSyncCryptAuthV2DeviceManagerImplTest ...@@ -293,6 +300,8 @@ class DeviceSyncCryptAuthV2DeviceManagerImplTest
std::unique_ptr<CryptAuthDeviceRegistry> device_registry_; std::unique_ptr<CryptAuthDeviceRegistry> device_registry_;
std::unique_ptr<CryptAuthKeyRegistry> key_registry_; std::unique_ptr<CryptAuthKeyRegistry> key_registry_;
std::unique_ptr<FakeCryptAuthDeviceSyncerFactory> fake_device_syncer_factory_; std::unique_ptr<FakeCryptAuthDeviceSyncerFactory> fake_device_syncer_factory_;
FakeSyncedBluetoothAddressTrackerFactory
fake_synced_bluetooth_address_tracker_factory_;
std::unique_ptr<CryptAuthV2DeviceManager> device_manager_; std::unique_ptr<CryptAuthV2DeviceManager> device_manager_;
}; };
......
...@@ -19,6 +19,7 @@ namespace device_sync { ...@@ -19,6 +19,7 @@ namespace device_sync {
const char kGroupPublicKey[] = "group_key"; const char kGroupPublicKey[] = "group_key";
const int64_t kGroupPublicKeyHash = 0xf3666041a2db06e4; const int64_t kGroupPublicKeyHash = 0xf3666041a2db06e4;
const char kDefaultLocalDeviceBluetoothAddress[] = "01:23:45:67:89:AB";
const CryptAuthDevice& GetLocalDeviceForTest() { const CryptAuthDevice& GetLocalDeviceForTest() {
static const base::NoDestructor<CryptAuthDevice> device([] { static const base::NoDestructor<CryptAuthDevice> device([] {
...@@ -34,6 +35,8 @@ const CryptAuthDevice& GetLocalDeviceForTest() { ...@@ -34,6 +35,8 @@ const CryptAuthDevice& GetLocalDeviceForTest() {
bt_metadata.set_public_key(kLocalDeviceUserPublicKey); bt_metadata.set_public_key(kLocalDeviceUserPublicKey);
bt_metadata.set_no_pii_device_name( bt_metadata.set_no_pii_device_name(
cryptauthv2::GetClientAppMetadataForTest().device_model()); cryptauthv2::GetClientAppMetadataForTest().device_model());
bt_metadata.set_bluetooth_public_address(
kDefaultLocalDeviceBluetoothAddress);
return CryptAuthDevice( return CryptAuthDevice(
cryptauthv2::GetClientAppMetadataForTest().instance_id(), cryptauthv2::GetClientAppMetadataForTest().instance_id(),
......
...@@ -41,6 +41,9 @@ extern const char kGroupPublicKey[]; ...@@ -41,6 +41,9 @@ extern const char kGroupPublicKey[];
// the group private key. // the group private key.
extern const int64_t kGroupPublicKeyHash; extern const int64_t kGroupPublicKeyHash;
// Bluetooth address for the local device.
extern const char kDefaultLocalDeviceBluetoothAddress[];
// Three test devices: The local device, a remote device that needs the group // Three test devices: The local device, a remote device that needs the group
// private key, and a remote device that has the group private key. // private key, and a remote device that has the group private key.
const CryptAuthDevice& GetLocalDeviceForTest(); const CryptAuthDevice& GetLocalDeviceForTest();
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "chromeos/services/device_sync/public/cpp/gcm_device_info_provider.h" #include "chromeos/services/device_sync/public/cpp/gcm_device_info_provider.h"
#include "chromeos/services/device_sync/remote_device_provider_impl.h" #include "chromeos/services/device_sync/remote_device_provider_impl.h"
#include "chromeos/services/device_sync/software_feature_manager_impl.h" #include "chromeos/services/device_sync/software_feature_manager_impl.h"
#include "chromeos/services/device_sync/synced_bluetooth_address_tracker_impl.h"
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/signin/public/identity_manager/consent_level.h" #include "components/signin/public/identity_manager/consent_level.h"
...@@ -338,6 +339,7 @@ void DeviceSyncImpl::RegisterProfilePrefs(PrefRegistrySimple* registry) { ...@@ -338,6 +339,7 @@ void DeviceSyncImpl::RegisterProfilePrefs(PrefRegistrySimple* registry) {
if (features::ShouldUseV2DeviceSync()) { if (features::ShouldUseV2DeviceSync()) {
CryptAuthDeviceRegistryImpl::RegisterPrefs(registry); CryptAuthDeviceRegistryImpl::RegisterPrefs(registry);
CryptAuthMetadataSyncerImpl::RegisterPrefs(registry); CryptAuthMetadataSyncerImpl::RegisterPrefs(registry);
SyncedBluetoothAddressTrackerImpl::RegisterPrefs(registry);
} }
} }
......
...@@ -37,11 +37,13 @@ FakeCryptAuthDeviceSyncerFactory::CreateInstance( ...@@ -37,11 +37,13 @@ FakeCryptAuthDeviceSyncerFactory::CreateInstance(
CryptAuthDeviceRegistry* device_registry, CryptAuthDeviceRegistry* device_registry,
CryptAuthKeyRegistry* key_registry, CryptAuthKeyRegistry* key_registry,
CryptAuthClientFactory* client_factory, CryptAuthClientFactory* client_factory,
SyncedBluetoothAddressTracker* synced_bluetooth_address_tracker,
PrefService* pref_service, PrefService* pref_service,
std::unique_ptr<base::OneShotTimer> timer) { std::unique_ptr<base::OneShotTimer> timer) {
last_device_registry_ = device_registry; last_device_registry_ = device_registry;
last_key_registry_ = key_registry; last_key_registry_ = key_registry;
last_client_factory_ = client_factory; last_client_factory_ = client_factory;
last_synced_bluetooth_address_tracker_ = synced_bluetooth_address_tracker;
last_pref_service_ = pref_service; last_pref_service_ = pref_service;
auto instance = std::make_unique<FakeCryptAuthDeviceSyncer>(); auto instance = std::make_unique<FakeCryptAuthDeviceSyncer>();
......
...@@ -81,6 +81,7 @@ class FakeCryptAuthDeviceSyncerFactory ...@@ -81,6 +81,7 @@ class FakeCryptAuthDeviceSyncerFactory
CryptAuthDeviceRegistry* device_registry, CryptAuthDeviceRegistry* device_registry,
CryptAuthKeyRegistry* key_registry, CryptAuthKeyRegistry* key_registry,
CryptAuthClientFactory* client_factory, CryptAuthClientFactory* client_factory,
SyncedBluetoothAddressTracker* synced_bluetooth_address_tracker,
PrefService* pref_service, PrefService* pref_service,
std::unique_ptr<base::OneShotTimer> timer) override; std::unique_ptr<base::OneShotTimer> timer) override;
...@@ -88,6 +89,8 @@ class FakeCryptAuthDeviceSyncerFactory ...@@ -88,6 +89,8 @@ class FakeCryptAuthDeviceSyncerFactory
CryptAuthDeviceRegistry* last_device_registry_ = nullptr; CryptAuthDeviceRegistry* last_device_registry_ = nullptr;
CryptAuthKeyRegistry* last_key_registry_ = nullptr; CryptAuthKeyRegistry* last_key_registry_ = nullptr;
CryptAuthClientFactory* last_client_factory_ = nullptr; CryptAuthClientFactory* last_client_factory_ = nullptr;
SyncedBluetoothAddressTracker* last_synced_bluetooth_address_tracker_ =
nullptr;
PrefService* last_pref_service_ = nullptr; PrefService* last_pref_service_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(FakeCryptAuthDeviceSyncerFactory); DISALLOW_COPY_AND_ASSIGN(FakeCryptAuthDeviceSyncerFactory);
......
...@@ -23,6 +23,7 @@ void FakeCryptAuthScheduler::RequestEnrollment( ...@@ -23,6 +23,7 @@ void FakeCryptAuthScheduler::RequestEnrollment(
const base::Optional<std::string>& session_id) { const base::Optional<std::string>& session_id) {
DCHECK(HasEnrollmentSchedulingStarted()); DCHECK(HasEnrollmentSchedulingStarted());
is_waiting_for_enrollment_result_ = true; is_waiting_for_enrollment_result_ = true;
++num_enrollment_requests_;
cryptauthv2::ClientMetadata client_metadata; cryptauthv2::ClientMetadata client_metadata;
client_metadata.set_retry_count(num_consecutive_enrollment_failures_); client_metadata.set_retry_count(num_consecutive_enrollment_failures_);
...@@ -39,6 +40,7 @@ void FakeCryptAuthScheduler::RequestDeviceSync( ...@@ -39,6 +40,7 @@ void FakeCryptAuthScheduler::RequestDeviceSync(
const base::Optional<std::string>& session_id) { const base::Optional<std::string>& session_id) {
DCHECK(HasDeviceSyncSchedulingStarted()); DCHECK(HasDeviceSyncSchedulingStarted());
is_waiting_for_device_sync_result_ = true; is_waiting_for_device_sync_result_ = true;
++num_sync_requests_;
cryptauthv2::ClientMetadata client_metadata; cryptauthv2::ClientMetadata client_metadata;
client_metadata.set_retry_count(num_consecutive_device_sync_failures_); client_metadata.set_retry_count(num_consecutive_device_sync_failures_);
......
...@@ -31,6 +31,9 @@ class FakeCryptAuthScheduler : public CryptAuthScheduler { ...@@ -31,6 +31,9 @@ class FakeCryptAuthScheduler : public CryptAuthScheduler {
FakeCryptAuthScheduler(); FakeCryptAuthScheduler();
~FakeCryptAuthScheduler() override; ~FakeCryptAuthScheduler() override;
size_t num_enrollment_requests() const { return num_enrollment_requests_; }
size_t num_sync_requests() const { return num_sync_requests_; }
const std::vector<CryptAuthEnrollmentResult>& handled_enrollment_results() const std::vector<CryptAuthEnrollmentResult>& handled_enrollment_results()
const { const {
return handled_enrollment_results_; return handled_enrollment_results_;
...@@ -116,6 +119,8 @@ class FakeCryptAuthScheduler : public CryptAuthScheduler { ...@@ -116,6 +119,8 @@ class FakeCryptAuthScheduler : public CryptAuthScheduler {
base::Optional<base::TimeDelta> time_to_next_enrollment_request_ = base::Optional<base::TimeDelta> time_to_next_enrollment_request_ =
kDefaultTimeToNextEnrollmentRequest; kDefaultTimeToNextEnrollmentRequest;
base::Optional<base::TimeDelta> time_to_next_device_sync_request_; base::Optional<base::TimeDelta> time_to_next_device_sync_request_;
size_t num_enrollment_requests_ = 0u;
size_t num_sync_requests_ = 0u;
size_t num_consecutive_enrollment_failures_ = 0u; size_t num_consecutive_enrollment_failures_ = 0u;
size_t num_consecutive_device_sync_failures_ = 0u; size_t num_consecutive_device_sync_failures_ = 0u;
bool is_waiting_for_enrollment_result_ = false; bool is_waiting_for_enrollment_result_ = false;
......
// Copyright 2020 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/services/device_sync/fake_synced_bluetooth_address_tracker.h"
namespace chromeos {
namespace device_sync {
FakeSyncedBluetoothAddressTracker::FakeSyncedBluetoothAddressTracker() =
default;
FakeSyncedBluetoothAddressTracker::~FakeSyncedBluetoothAddressTracker() =
default;
void FakeSyncedBluetoothAddressTracker::GetBluetoothAddress(
BluetoothAddressCallback callback) {
std::move(callback).Run(bluetooth_address_);
}
void FakeSyncedBluetoothAddressTracker::SetLastSyncedBluetoothAddress(
const std::string& last_synced_bluetooth_address) {
last_synced_bluetooth_address_ = last_synced_bluetooth_address;
}
FakeSyncedBluetoothAddressTrackerFactory::
FakeSyncedBluetoothAddressTrackerFactory() = default;
FakeSyncedBluetoothAddressTrackerFactory::
~FakeSyncedBluetoothAddressTrackerFactory() = default;
std::unique_ptr<SyncedBluetoothAddressTracker>
FakeSyncedBluetoothAddressTrackerFactory::CreateInstance(
CryptAuthScheduler* cryptauth_scheduler,
PrefService* pref_service) {
auto instance = std::make_unique<FakeSyncedBluetoothAddressTracker>();
last_created_ = instance.get();
return instance;
}
} // namespace device_sync
} // namespace chromeos
// Copyright 2020 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_SERVICES_DEVICE_SYNC_FAKE_SYNCED_BLUETOOTH_ADDRESS_TRACKER_H_
#define CHROMEOS_SERVICES_DEVICE_SYNC_FAKE_SYNCED_BLUETOOTH_ADDRESS_TRACKER_H_
#include "chromeos/services/device_sync/cryptauth_v2_device_sync_test_devices.h"
#include "chromeos/services/device_sync/synced_bluetooth_address_tracker.h"
#include "chromeos/services/device_sync/synced_bluetooth_address_tracker_impl.h"
namespace chromeos {
namespace device_sync {
class FakeSyncedBluetoothAddressTracker : public SyncedBluetoothAddressTracker {
public:
FakeSyncedBluetoothAddressTracker();
~FakeSyncedBluetoothAddressTracker() override;
void set_bluetooth_address(const std::string& bluetooth_address) {
bluetooth_address_ = bluetooth_address;
}
const std::string& last_synced_bluetooth_address() const {
return last_synced_bluetooth_address_;
}
private:
// SyncedBluetoothAddressTracker:
void GetBluetoothAddress(BluetoothAddressCallback callback) override;
void SetLastSyncedBluetoothAddress(
const std::string& last_synced_bluetooth_address) override;
std::string bluetooth_address_ = kDefaultLocalDeviceBluetoothAddress;
std::string last_synced_bluetooth_address_;
};
class FakeSyncedBluetoothAddressTrackerFactory
: public SyncedBluetoothAddressTrackerImpl::Factory {
public:
FakeSyncedBluetoothAddressTrackerFactory();
~FakeSyncedBluetoothAddressTrackerFactory() override;
SyncedBluetoothAddressTracker* last_created() { return last_created_; }
private:
// SyncedBluetoothAddressTracker::Factory:
std::unique_ptr<SyncedBluetoothAddressTracker> CreateInstance(
CryptAuthScheduler* cryptauth_scheduler,
PrefService* pref_service) override;
SyncedBluetoothAddressTracker* last_created_ = nullptr;
};
} // namespace device_sync
} // namespace chromeos
#endif // CHROMEOS_SERVICES_DEVICE_SYNC_FAKE_SYNCED_BLUETOOTH_ADDRESS_TRACKER_H_
...@@ -86,6 +86,11 @@ const char kCryptAuthLastSyncedGroupPublicKey[] = ...@@ -86,6 +86,11 @@ const char kCryptAuthLastSyncedGroupPublicKey[] =
const char kCryptAuthLastSyncedUnencryptedLocalDeviceMetadata[] = const char kCryptAuthLastSyncedUnencryptedLocalDeviceMetadata[] =
"cryptauth.device_sync.last_synced_unencrypted_local_device_metadata"; "cryptauth.device_sync.last_synced_unencrypted_local_device_metadata";
// (CryptAuth v2) The Bluetooth address provided during the most recent
// DeviceSync attempt.
const char kCryptAuthBluetoothAddressProvidedDuringLastSync[] =
"cryptauth.device_sync.last_bluetooth_address";
// (CryptAuth v2) The most recent ClientDirective sent to the // (CryptAuth v2) The most recent ClientDirective sent to the
// CryptAuthScheduler. // CryptAuthScheduler.
const char kCryptAuthSchedulerClientDirective[] = const char kCryptAuthSchedulerClientDirective[] =
......
...@@ -34,6 +34,7 @@ extern const char kCryptAuthLastEnrolledClientAppMetadataHash[]; ...@@ -34,6 +34,7 @@ extern const char kCryptAuthLastEnrolledClientAppMetadataHash[];
extern const char kCryptAuthLastSyncedEncryptedLocalDeviceMetadata[]; extern const char kCryptAuthLastSyncedEncryptedLocalDeviceMetadata[];
extern const char kCryptAuthLastSyncedGroupPublicKey[]; extern const char kCryptAuthLastSyncedGroupPublicKey[];
extern const char kCryptAuthLastSyncedUnencryptedLocalDeviceMetadata[]; extern const char kCryptAuthLastSyncedUnencryptedLocalDeviceMetadata[];
extern const char kCryptAuthBluetoothAddressProvidedDuringLastSync[];
extern const char kCryptAuthSchedulerClientDirective[]; extern const char kCryptAuthSchedulerClientDirective[];
extern const char kCryptAuthSchedulerNextEnrollmentRequestClientMetadata[]; extern const char kCryptAuthSchedulerNextEnrollmentRequestClientMetadata[];
extern const char kCryptAuthSchedulerNextDeviceSyncRequestClientMetadata[]; extern const char kCryptAuthSchedulerNextDeviceSyncRequestClientMetadata[];
......
// Copyright 2020 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_SERVICES_DEVICE_SYNC_SYNCED_BLUETOOTH_ADDRESS_TRACKER_H_
#define CHROMEOS_SERVICES_DEVICE_SYNC_SYNCED_BLUETOOTH_ADDRESS_TRACKER_H_
#include <string>
#include "base/callback.h"
#include "base/optional.h"
namespace chromeos {
namespace device_sync {
// Provides a Bluetooth address to add to the encrypted metadata synced via
// DeviceSync v2, and triggers a new sync if this address has changed (e.g., if
// the user inserts a USB Bluetooth adapter).
class SyncedBluetoothAddressTracker {
public:
virtual ~SyncedBluetoothAddressTracker() = default;
SyncedBluetoothAddressTracker(const SyncedBluetoothAddressTracker&) = delete;
SyncedBluetoothAddressTracker& operator=(
const SyncedBluetoothAddressTracker&) = delete;
// Returns the device's Bluetooth address, formatted as a capitalized hex
// string with colons to separate bytes (example: "01:23:45:67:89:AB"). If the
// device does not have a Bluetooth adapter, an empty string is returned.
using BluetoothAddressCallback = base::OnceCallback<void(const std::string&)>;
virtual void GetBluetoothAddress(BluetoothAddressCallback callback) = 0;
// Sets the last Bluetooth address provided during a DeviceSync attempt.
// Should only be called after a successful sync.
virtual void SetLastSyncedBluetoothAddress(
const std::string& last_synced_address) = 0;
protected:
SyncedBluetoothAddressTracker() = default;
};
} // namespace device_sync
} // namespace chromeos
#endif // CHROMEOS_SERVICES_DEVICE_SYNC_SYNCED_BLUETOOTH_ADDRESS_TRACKER_H_
// Copyright 2020 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/services/device_sync/synced_bluetooth_address_tracker_impl.h"
#include <utility>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "chromeos/components/multidevice/logging/logging.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/device_sync/cryptauth_scheduler.h"
#include "chromeos/services/device_sync/pref_names.h"
#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
namespace chromeos {
namespace device_sync {
// Value stored in the kCryptAuthBluetoothAddressProvidedDuringLastSync pref
// when a Bluetooth address has not yet been provided after a successful
// DeviceSync attempt.
const char kHasNotSyncedYetPrefValue[] = "hasNotSyncedYet";
// static
SyncedBluetoothAddressTrackerImpl::Factory*
SyncedBluetoothAddressTrackerImpl::Factory::test_factory_ = nullptr;
// static
std::unique_ptr<SyncedBluetoothAddressTracker>
SyncedBluetoothAddressTrackerImpl::Factory::Create(
CryptAuthScheduler* cryptauth_scheduler,
PrefService* pref_service) {
if (test_factory_) {
return test_factory_->CreateInstance(cryptauth_scheduler, pref_service);
}
return base::WrapUnique(
new SyncedBluetoothAddressTrackerImpl(cryptauth_scheduler, pref_service));
}
// static
void SyncedBluetoothAddressTrackerImpl::Factory::SetFactoryForTesting(
Factory* test_factory) {
test_factory_ = test_factory;
}
SyncedBluetoothAddressTrackerImpl::Factory::~Factory() = default;
// static
void SyncedBluetoothAddressTrackerImpl::RegisterPrefs(
PrefRegistrySimple* registry) {
registry->RegisterStringPref(
prefs::kCryptAuthBluetoothAddressProvidedDuringLastSync,
kHasNotSyncedYetPrefValue);
}
SyncedBluetoothAddressTrackerImpl::SyncedBluetoothAddressTrackerImpl(
CryptAuthScheduler* cryptauth_scheduler,
PrefService* pref_service)
: cryptauth_scheduler_(cryptauth_scheduler), pref_service_(pref_service) {
// If the flag is disabled, set the pref to the "has not synced" state. This
// ensures that when the flag is enabled, the device kicks off a DeviceSync
// attempt with the address, which may not have happened in the case that the
// flag was flipped on, off, then on again.
if (!features::IsPhoneHubEnabled()) {
pref_service_->SetString(
prefs::kCryptAuthBluetoothAddressProvidedDuringLastSync,
kHasNotSyncedYetPrefValue);
}
device::BluetoothAdapterFactory::Get()->GetAdapter(base::BindOnce(
&SyncedBluetoothAddressTrackerImpl::OnBluetoothAdapterReceived,
weak_ptr_factory_.GetWeakPtr()));
}
SyncedBluetoothAddressTrackerImpl::~SyncedBluetoothAddressTrackerImpl() {
if (bluetooth_adapter_)
bluetooth_adapter_->RemoveObserver(this);
}
void SyncedBluetoothAddressTrackerImpl::GetBluetoothAddress(
BluetoothAddressCallback callback) {
if (!bluetooth_adapter_) {
pending_callbacks_during_init_.push_back(std::move(callback));
return;
}
std::move(callback).Run(GetAddress());
}
void SyncedBluetoothAddressTrackerImpl::SetLastSyncedBluetoothAddress(
const std::string& last_synced_address) {
// No pref should be stored with the flag disabled.
if (!features::IsPhoneHubEnabled())
return;
if (last_synced_address.empty()) {
PA_LOG(VERBOSE) << "Recording successful DeviceSync without a Bluetooth "
<< "address.";
} else {
PA_LOG(INFO) << "Recording successful DeviceSync with Bluetooth address: "
<< last_synced_address;
}
pref_service_->SetString(
prefs::kCryptAuthBluetoothAddressProvidedDuringLastSync,
last_synced_address);
}
void SyncedBluetoothAddressTrackerImpl::AdapterPresentChanged(
device::BluetoothAdapter* adapter,
bool present) {
DCHECK_EQ(adapter, bluetooth_adapter_.get());
if (present)
ScheduleSyncIfAddressChanged();
}
void SyncedBluetoothAddressTrackerImpl::OnBluetoothAdapterReceived(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) {
bluetooth_adapter_ = std::move(bluetooth_adapter);
bluetooth_adapter_->AddObserver(this);
for (auto& callback : pending_callbacks_during_init_)
std::move(callback).Run(GetAddress());
pending_callbacks_during_init_.clear();
ScheduleSyncIfAddressChanged();
}
void SyncedBluetoothAddressTrackerImpl::ScheduleSyncIfAddressChanged() {
// No sync should be scheduled if the flag is off.
if (!features::IsPhoneHubEnabled())
return;
std::string address_from_last_sync = pref_service_->GetString(
prefs::kCryptAuthBluetoothAddressProvidedDuringLastSync);
// If we've already synced and the Bluetooth address has changed (perhaps due
// to the user inserting a USB Bluetooth adapter), we should sync this new
// address. Return early if this is not the case.
if (GetAddress().empty() ||
address_from_last_sync == kHasNotSyncedYetPrefValue ||
address_from_last_sync == GetAddress()) {
return;
}
PA_LOG(INFO) << "Bluetooth address has changed since last DeviceSync. "
<< "Requesting new DeviceSync attempt.";
cryptauth_scheduler_->RequestDeviceSync(
cryptauthv2::ClientMetadata::InvocationReason::
ClientMetadata_InvocationReason_ADDRESS_CHANGE,
/*session_id=*/base::nullopt);
}
std::string SyncedBluetoothAddressTrackerImpl::GetAddress() {
DCHECK(bluetooth_adapter_);
if (features::IsPhoneHubEnabled())
return bluetooth_adapter_->GetAddress();
// Return an empty string if the flag is disabled.
return std::string();
}
} // namespace device_sync
} // namespace chromeos
// Copyright 2020 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_SERVICES_DEVICE_SYNC_SYNCED_BLUETOOTH_ADDRESS_TRACKER_IMPL_H_
#define CHROMEOS_SERVICES_DEVICE_SYNC_SYNCED_BLUETOOTH_ADDRESS_TRACKER_IMPL_H_
#include <memory>
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/services/device_sync/synced_bluetooth_address_tracker.h"
#include "device/bluetooth/bluetooth_adapter.h"
class PrefRegistrySimple;
class PrefService;
namespace device {
class BluetoothAdapter;
} // namespace device
namespace chromeos {
namespace device_sync {
class CryptAuthScheduler;
// SyncedBluetoothAddressTracker implementation which uses profile prefs to
// store the last synced Bluetooth address. If the address changes, it triggers
// a new DeviceSync attempt via CryptAuthScheduler.
class SyncedBluetoothAddressTrackerImpl
: public SyncedBluetoothAddressTracker,
public device::BluetoothAdapter::Observer {
public:
class Factory {
public:
static std::unique_ptr<SyncedBluetoothAddressTracker> Create(
CryptAuthScheduler* cryptauth_scheduler,
PrefService* pref_service);
static void SetFactoryForTesting(Factory* test_factory);
protected:
virtual ~Factory();
virtual std::unique_ptr<SyncedBluetoothAddressTracker> CreateInstance(
CryptAuthScheduler* cryptauth_scheduler,
PrefService* pref_service) = 0;
private:
static Factory* test_factory_;
};
static void RegisterPrefs(PrefRegistrySimple* registry);
~SyncedBluetoothAddressTrackerImpl() override;
// device::BluetoothAdapter::Observer:
void AdapterPresentChanged(device::BluetoothAdapter* adapter,
bool present) override;
private:
SyncedBluetoothAddressTrackerImpl(CryptAuthScheduler* cryptauth_scheduler,
PrefService* pref_service);
// SyncedBluetoothAddressTracker:
void GetBluetoothAddress(BluetoothAddressCallback callback) override;
void SetLastSyncedBluetoothAddress(
const std::string& last_synced_address) override;
void OnBluetoothAdapterReceived(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter);
void ScheduleSyncIfAddressChanged();
std::string GetAddress();
CryptAuthScheduler* cryptauth_scheduler_;
PrefService* pref_service_;
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
std::vector<BluetoothAddressCallback> pending_callbacks_during_init_;
base::WeakPtrFactory<SyncedBluetoothAddressTrackerImpl> weak_ptr_factory_{
this};
};
} // namespace device_sync
} // namespace chromeos
#endif // CHROMEOS_SERVICES_DEVICE_SYNC_SYNCED_BLUETOOTH_ADDRESS_TRACKER_IMPL_H_
// Copyright 2020 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/services/device_sync/synced_bluetooth_address_tracker_impl.h"
#include <memory>
#include <vector>
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/device_sync/fake_cryptauth_scheduler.h"
#include "chromeos/services/device_sync/pref_names.h"
#include "components/prefs/testing_pref_service.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace device_sync {
namespace {
const char kHasNotSyncedYetPrefValue[] = "hasNotSyncedYet";
const char kDefaultAdapterAddress[] = "01:23:45:67:89:AB";
} // namespace
class DeviceSyncSyncedBluetoothAddressTrackerImplTest : public testing::Test {
protected:
DeviceSyncSyncedBluetoothAddressTrackerImplTest() = default;
DeviceSyncSyncedBluetoothAddressTrackerImplTest(
const DeviceSyncSyncedBluetoothAddressTrackerImplTest&) = delete;
DeviceSyncSyncedBluetoothAddressTrackerImplTest& operator=(
const DeviceSyncSyncedBluetoothAddressTrackerImplTest&) = delete;
~DeviceSyncSyncedBluetoothAddressTrackerImplTest() override = default;
// testing::Test:
void SetUp() override {
mock_adapter_ =
base::MakeRefCounted<testing::NiceMock<device::MockBluetoothAdapter>>();
is_adapter_present_ = true;
ON_CALL(*mock_adapter_, IsPresent())
.WillByDefault(
Invoke(this, &DeviceSyncSyncedBluetoothAddressTrackerImplTest::
is_adapter_present));
ON_CALL(*mock_adapter_, GetAddress())
.WillByDefault(Invoke(
this,
&DeviceSyncSyncedBluetoothAddressTrackerImplTest::adapter_address));
device::BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_);
fake_cryptauth_scheduler_.StartDeviceSyncScheduling(
fake_device_sync_delegate_.GetWeakPtr());
SyncedBluetoothAddressTrackerImpl::RegisterPrefs(pref_service_.registry());
}
void Initialize(bool is_flag_enabled,
const std::string& initial_bluetooth_pref_value) {
static const std::vector<base::Feature> kPhoneHubFeatureVector{
chromeos::features::kPhoneHub};
static const std::vector<base::Feature> kNoFeaturesVector;
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/is_flag_enabled ? kPhoneHubFeatureVector
: kNoFeaturesVector,
/*disabled_features=*/is_flag_enabled ? kNoFeaturesVector
: kPhoneHubFeatureVector);
pref_service_.SetString(
prefs::kCryptAuthBluetoothAddressProvidedDuringLastSync,
initial_bluetooth_pref_value);
tracker_ = SyncedBluetoothAddressTrackerImpl::Factory::Create(
&fake_cryptauth_scheduler_, &pref_service_);
}
std::string GetBluetoothAddress() {
std::string address_to_return;
base::RunLoop run_loop;
tracker_->GetBluetoothAddress(
base::BindLambdaForTesting([&](const std::string& address) {
address_to_return = address;
run_loop.Quit();
}));
run_loop.Run();
return address_to_return;
}
std::string GetAddressStoredInPrefs() {
return pref_service_.GetString(
prefs::kCryptAuthBluetoothAddressProvidedDuringLastSync);
}
SyncedBluetoothAddressTracker& tracker() { return *tracker_; }
const FakeCryptAuthScheduler& fake_cryptauth_scheduler() const {
return fake_cryptauth_scheduler_;
}
void set_adapter_address(const std::string& adapter_address) {
adapter_address_ = adapter_address;
}
void SetAdapterPresentState(bool present) {
is_adapter_present_ = present;
if (tracker_) {
SyncedBluetoothAddressTrackerImpl* impl =
static_cast<SyncedBluetoothAddressTrackerImpl*>(tracker_.get());
impl->AdapterPresentChanged(mock_adapter_.get(), present);
}
}
private:
bool is_adapter_present() { return is_adapter_present_; }
const std::string& adapter_address() { return adapter_address_; }
base::test::TaskEnvironment task_environment_;
base::test::ScopedFeatureList scoped_feature_list_;
scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>> mock_adapter_;
FakeCryptAuthScheduler fake_cryptauth_scheduler_;
FakeCryptAuthSchedulerDeviceSyncDelegate fake_device_sync_delegate_;
TestingPrefServiceSimple pref_service_;
bool is_adapter_present_ = true;
std::string adapter_address_ = kDefaultAdapterAddress;
std::unique_ptr<SyncedBluetoothAddressTracker> tracker_;
};
TEST_F(DeviceSyncSyncedBluetoothAddressTrackerImplTest, FlagOff) {
Initialize(/*is_flag_enabled=*/false, kHasNotSyncedYetPrefValue);
// When the flag is off, an empty string is returned, even though the adapter
// has the default address.
EXPECT_TRUE(GetBluetoothAddress().empty());
// When the flag is off, setting the last synced address does nothing.
tracker().SetLastSyncedBluetoothAddress(kDefaultAdapterAddress);
EXPECT_EQ(kHasNotSyncedYetPrefValue, GetAddressStoredInPrefs());
EXPECT_EQ(0u, fake_cryptauth_scheduler().num_sync_requests());
}
TEST_F(DeviceSyncSyncedBluetoothAddressTrackerImplTest, HastNotSynced) {
Initialize(/*is_flag_enabled=*/true, kHasNotSyncedYetPrefValue);
EXPECT_EQ(kDefaultAdapterAddress, GetBluetoothAddress());
tracker().SetLastSyncedBluetoothAddress(kDefaultAdapterAddress);
EXPECT_EQ(kDefaultAdapterAddress, GetAddressStoredInPrefs());
EXPECT_EQ(0u, fake_cryptauth_scheduler().num_sync_requests());
}
TEST_F(DeviceSyncSyncedBluetoothAddressTrackerImplTest, ChangedAddress) {
// Initialize with a different address from kDefaultAdapterAddress.
Initialize(/*is_flag_enabled=*/true, "23:45:67:89:AB:CD");
// Address changed, so a new sync should have been triggered.
EXPECT_EQ(1u, fake_cryptauth_scheduler().num_sync_requests());
}
TEST_F(DeviceSyncSyncedBluetoothAddressTrackerImplTest, SameAddress) {
Initialize(/*is_flag_enabled=*/true, kDefaultAdapterAddress);
// Address has not changed, so no new sync should have been triggered.
EXPECT_EQ(0u, fake_cryptauth_scheduler().num_sync_requests());
}
TEST_F(DeviceSyncSyncedBluetoothAddressTrackerImplTest, AdapterPresent) {
// Simulate a user already having synced but having no Bluetooth adapter.
SetAdapterPresentState(false);
set_adapter_address(std::string());
Initialize(/*is_flag_enabled=*/true, std::string());
// Adapter is not present.
EXPECT_EQ(0u, fake_cryptauth_scheduler().num_sync_requests());
EXPECT_TRUE(GetBluetoothAddress().empty());
// Now, simulate the usr plugging in a USB Bluetooth adapter.
set_adapter_address(kDefaultAdapterAddress);
SetAdapterPresentState(true);
// Address changed, so a new sync should have been triggered.
EXPECT_EQ(1u, fake_cryptauth_scheduler().num_sync_requests());
}
} // namespace device_sync
} // namespace chromeos
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