Commit f1e621cd authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS MultiDevice] DeviceSync: Implement GetDebugInfo() API function.

This function returns various debug data about the DeviceSync service
and is intended to be used only by the chrome://proximity-auth debug
page.

Bug: 824568, 752273
Change-Id: Iaea72dfcb251488cc42c1211c3143b25d96b48cf
Reviewed-on: https://chromium-review.googlesource.com/1020155
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarJeremy Klein <jlklein@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553366}
parent 7ded5b13
...@@ -216,6 +216,25 @@ void DeviceSyncImpl::FindEligibleDevices( ...@@ -216,6 +216,25 @@ void DeviceSyncImpl::FindEligibleDevices(
weak_ptr_factory_.GetWeakPtr(), callback_holder)); weak_ptr_factory_.GetWeakPtr(), callback_holder));
} }
void DeviceSyncImpl::GetDebugInfo(GetDebugInfoCallback callback) {
if (status_ != Status::READY) {
PA_LOG(WARNING) << "DeviceSyncImpl::GetDebugInfo() invoked before "
<< "initialization was complete. Cannot provide info.";
std::move(callback).Run(nullptr);
return;
}
std::move(callback).Run(mojom::DebugInfo::New(
cryptauth_enrollment_manager_->GetLastEnrollmentTime(),
cryptauth_enrollment_manager_->GetTimeToNextAttempt(),
cryptauth_enrollment_manager_->IsRecoveringFromFailure(),
cryptauth_enrollment_manager_->IsEnrollmentInProgress(),
cryptauth_device_manager_->GetLastSyncTime(),
cryptauth_device_manager_->GetTimeToNextAttempt(),
cryptauth_device_manager_->IsRecoveringFromFailure(),
cryptauth_device_manager_->IsSyncInProgress()));
}
void DeviceSyncImpl::OnEnrollmentFinished(bool success) { void DeviceSyncImpl::OnEnrollmentFinished(bool success) {
PA_LOG(INFO) << "DeviceSyncImpl: Enrollment finished; success = " << success; PA_LOG(INFO) << "DeviceSyncImpl: Enrollment finished; success = " << success;
......
...@@ -105,6 +105,7 @@ class DeviceSyncImpl : public mojom::DeviceSync, ...@@ -105,6 +105,7 @@ class DeviceSyncImpl : public mojom::DeviceSync,
SetSoftwareFeatureStateCallback callback) override; SetSoftwareFeatureStateCallback callback) override;
void FindEligibleDevices(cryptauth::SoftwareFeature software_feature, void FindEligibleDevices(cryptauth::SoftwareFeature software_feature,
FindEligibleDevicesCallback callback) override; FindEligibleDevicesCallback callback) override;
void GetDebugInfo(GetDebugInfoCallback callback) override;
// cryptauth::CryptAuthEnrollmentManager::Observer: // cryptauth::CryptAuthEnrollmentManager::Observer:
void OnEnrollmentFinished(bool success) override; void OnEnrollmentFinished(bool success) override;
......
...@@ -650,6 +650,15 @@ class DeviceSyncServiceTest : public testing::Test { ...@@ -650,6 +650,15 @@ class DeviceSyncServiceTest : public testing::Test {
return fake_pref_connection_delegate_; return fake_pref_connection_delegate_;
} }
cryptauth::FakeCryptAuthEnrollmentManager*
fake_cryptauth_enrollment_manager() {
return fake_cryptauth_enrollment_manager_factory_->instance();
}
cryptauth::FakeCryptAuthDeviceManager* fake_cryptauth_device_manager() {
return fake_cryptauth_device_manager_factory_->instance();
}
cryptauth::FakeSoftwareFeatureManager* fake_software_feature_manager() { cryptauth::FakeSoftwareFeatureManager* fake_software_feature_manager() {
return fake_software_feature_manager_factory_->instance(); return fake_software_feature_manager_factory_->instance();
} }
...@@ -690,6 +699,9 @@ class DeviceSyncServiceTest : public testing::Test { ...@@ -690,6 +699,9 @@ class DeviceSyncServiceTest : public testing::Test {
auto last_find_response = GetLastFindEligibleDevicesResponseAndReset(); auto last_find_response = GetLastFindEligibleDevicesResponseAndReset();
EXPECT_EQ(mojom::kErrorNotInitialized, last_find_response->first); EXPECT_EQ(mojom::kErrorNotInitialized, last_find_response->first);
EXPECT_FALSE(last_find_response->second /* response */); EXPECT_FALSE(last_find_response->second /* response */);
// GetDebugInfo() returns a null DebugInfo before initialization.
EXPECT_FALSE(CallGetDebugInfo());
} }
void CallAddObserver() { void CallAddObserver() {
...@@ -807,6 +819,15 @@ class DeviceSyncServiceTest : public testing::Test { ...@@ -807,6 +819,15 @@ class DeviceSyncServiceTest : public testing::Test {
fake_software_feature_manager_factory_->instance()->set_delegate(nullptr); fake_software_feature_manager_factory_->instance()->set_delegate(nullptr);
} }
const base::Optional<mojom::DebugInfo>& CallGetDebugInfo() {
base::RunLoop run_loop;
device_sync_->GetDebugInfo(
base::BindOnce(&DeviceSyncServiceTest::OnGetDebugInfoCompleted,
base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run();
return last_debug_info_result_;
}
private: private:
void OnAddObserverCompleted(base::OnceClosure quit_closure) { void OnAddObserverCompleted(base::OnceClosure quit_closure) {
std::move(quit_closure).Run(); std::move(quit_closure).Run();
...@@ -862,6 +883,16 @@ class DeviceSyncServiceTest : public testing::Test { ...@@ -862,6 +883,16 @@ class DeviceSyncServiceTest : public testing::Test {
std::move(quit_closure).Run(); std::move(quit_closure).Run();
} }
void OnGetDebugInfoCompleted(base::OnceClosure quit_closure,
mojom::DebugInfoPtr debug_info) {
EXPECT_FALSE(last_debug_info_result_);
if (debug_info)
last_debug_info_result_ = *debug_info;
else
last_debug_info_result_.reset();
std::move(quit_closure).Run();
}
const base::test::ScopedTaskEnvironment scoped_task_environment_; const base::test::ScopedTaskEnvironment scoped_task_environment_;
const cryptauth::RemoteDeviceList test_devices_; const cryptauth::RemoteDeviceList test_devices_;
const std::vector<cryptauth::ExternalDeviceInfo> test_device_infos_; const std::vector<cryptauth::ExternalDeviceInfo> test_device_infos_;
...@@ -900,6 +931,7 @@ class DeviceSyncServiceTest : public testing::Test { ...@@ -900,6 +931,7 @@ class DeviceSyncServiceTest : public testing::Test {
std::unique_ptr<std::pair<base::Optional<std::string>, std::unique_ptr<std::pair<base::Optional<std::string>,
mojom::FindEligibleDevicesResponsePtr>> mojom::FindEligibleDevicesResponsePtr>>
last_find_eligible_devices_response_; last_find_eligible_devices_response_;
base::Optional<mojom::DebugInfo> last_debug_info_result_;
std::unique_ptr<FakeDeviceSyncObserver> fake_device_sync_observer_; std::unique_ptr<FakeDeviceSyncObserver> fake_device_sync_observer_;
mojom::DeviceSyncPtr device_sync_; mojom::DeviceSyncPtr device_sync_;
...@@ -1146,6 +1178,51 @@ TEST_F(DeviceSyncServiceTest, FindEligibleDevices) { ...@@ -1146,6 +1178,51 @@ TEST_F(DeviceSyncServiceTest, FindEligibleDevices) {
EXPECT_FALSE(last_response->second /* response */); EXPECT_FALSE(last_response->second /* response */);
} }
TEST_F(DeviceSyncServiceTest, GetDebugInfo) {
static const base::TimeDelta kTimeBetweenEpochAndLastEnrollment =
base::TimeDelta::FromDays(365 * 50); // 50 years
static const base::TimeDelta kTimeUntilNextEnrollment =
base::TimeDelta::FromDays(10);
static const base::TimeDelta kTimeBetweenEpochAndLastSync =
base::TimeDelta::FromDays(366 * 50); // 50 years and 1 day
static const base::TimeDelta kTimeUntilNextSync =
base::TimeDelta::FromDays(11);
InitializeServiceSuccessfully();
fake_cryptauth_enrollment_manager()->set_last_enrollment_time(
base::Time::FromDeltaSinceWindowsEpoch(
kTimeBetweenEpochAndLastEnrollment));
fake_cryptauth_enrollment_manager()->set_time_to_next_attempt(
kTimeUntilNextEnrollment);
fake_cryptauth_enrollment_manager()->set_is_recovering_from_failure(false);
fake_cryptauth_enrollment_manager()->set_is_enrollment_in_progress(true);
fake_cryptauth_device_manager()->set_last_sync_time(
base::Time::FromDeltaSinceWindowsEpoch(kTimeBetweenEpochAndLastSync));
fake_cryptauth_device_manager()->set_time_to_next_attempt(kTimeUntilNextSync);
fake_cryptauth_device_manager()->set_is_recovering_from_failure(true);
fake_cryptauth_device_manager()->set_is_sync_in_progress(false);
const auto& result = CallGetDebugInfo();
EXPECT_TRUE(result);
EXPECT_EQ(base::Time::FromDeltaSinceWindowsEpoch(
kTimeBetweenEpochAndLastEnrollment),
result->last_enrollment_time);
EXPECT_EQ(base::TimeDelta(kTimeUntilNextEnrollment),
result->time_to_next_enrollment_attempt);
EXPECT_FALSE(result->is_recovering_from_enrollment_failure);
EXPECT_TRUE(result->is_enrollment_in_progress);
EXPECT_EQ(
base::Time::FromDeltaSinceWindowsEpoch(kTimeBetweenEpochAndLastSync),
result->last_sync_time);
EXPECT_EQ(base::TimeDelta(kTimeUntilNextSync),
result->time_to_next_sync_attempt);
EXPECT_TRUE(result->is_recovering_from_sync_failure);
EXPECT_FALSE(result->is_sync_in_progress);
}
} // namespace device_sync } // namespace device_sync
} // namespace chromeos } // namespace chromeos
...@@ -90,6 +90,20 @@ struct FindEligibleDevicesResponse { ...@@ -90,6 +90,20 @@ struct FindEligibleDevicesResponse {
array<RemoteDevice> ineligible_devices; array<RemoteDevice> ineligible_devices;
}; };
struct DebugInfo {
// Enrollment stats:
mojo_base.mojom.Time last_enrollment_time;
mojo_base.mojom.TimeDelta time_to_next_enrollment_attempt;
bool is_recovering_from_enrollment_failure;
bool is_enrollment_in_progress;
// Sync stats:
mojo_base.mojom.Time last_sync_time;
mojo_base.mojom.TimeDelta time_to_next_sync_attempt;
bool is_recovering_from_sync_failure;
bool is_sync_in_progress;
};
interface DeviceSyncObserver { interface DeviceSyncObserver {
// Invoked when the current device has successfully completed enrollment. Note // Invoked when the current device has successfully completed enrollment. Note
// that enrollment occurs once when the device first starts up, then the // that enrollment occurs once when the device first starts up, then the
...@@ -154,4 +168,10 @@ interface DeviceSync { ...@@ -154,4 +168,10 @@ interface DeviceSync {
// the reason for failure along with a null response. // the reason for failure along with a null response.
FindEligibleDevices(SoftwareFeature software_feature) => FindEligibleDevices(SoftwareFeature software_feature) =>
(string? error_code, FindEligibleDevicesResponse? response); (string? error_code, FindEligibleDevicesResponse? response);
// Functions below are implemented for chrome://proximity-auth page, which is
// intended for debugging purposes only.
// TODO(khorimoto): Determine whether a new, debug-only interface should be
// refactored out of DeviceSync.
GetDebugInfo() => (DebugInfo? debug_info);
}; };
...@@ -15,7 +15,7 @@ FakeCryptAuthDeviceManager::~FakeCryptAuthDeviceManager() = default; ...@@ -15,7 +15,7 @@ FakeCryptAuthDeviceManager::~FakeCryptAuthDeviceManager() = default;
void FakeCryptAuthDeviceManager::FinishActiveSync( void FakeCryptAuthDeviceManager::FinishActiveSync(
SyncResult sync_result, SyncResult sync_result,
DeviceChangeResult device_change_result, DeviceChangeResult device_change_result,
const base::Time& sync_finish_time) { base::Time sync_finish_time) {
DCHECK(is_sync_in_progress_); DCHECK(is_sync_in_progress_);
is_sync_in_progress_ = false; is_sync_in_progress_ = false;
......
...@@ -21,6 +21,10 @@ class FakeCryptAuthDeviceManager : public CryptAuthDeviceManager { ...@@ -21,6 +21,10 @@ class FakeCryptAuthDeviceManager : public CryptAuthDeviceManager {
bool has_started() { return has_started_; } bool has_started() { return has_started_; }
void set_last_sync_time(base::Time last_sync_time) {
last_sync_time_ = last_sync_time;
}
void set_time_to_next_attempt(base::TimeDelta time_to_next_attempt) { void set_time_to_next_attempt(base::TimeDelta time_to_next_attempt) {
time_to_next_attempt_ = time_to_next_attempt; time_to_next_attempt_ = time_to_next_attempt;
} }
...@@ -33,7 +37,7 @@ class FakeCryptAuthDeviceManager : public CryptAuthDeviceManager { ...@@ -33,7 +37,7 @@ class FakeCryptAuthDeviceManager : public CryptAuthDeviceManager {
std::vector<ExternalDeviceInfo>& unlock_keys() { return unlock_keys_; } std::vector<ExternalDeviceInfo>& unlock_keys() { return unlock_keys_; }
void set_unlock_keys(std::vector<ExternalDeviceInfo> unlock_keys) { void set_unlock_keys(const std::vector<ExternalDeviceInfo>& unlock_keys) {
unlock_keys_ = unlock_keys; unlock_keys_ = unlock_keys;
} }
...@@ -42,13 +46,13 @@ class FakeCryptAuthDeviceManager : public CryptAuthDeviceManager { ...@@ -42,13 +46,13 @@ class FakeCryptAuthDeviceManager : public CryptAuthDeviceManager {
} }
void set_pixel_unlock_keys( void set_pixel_unlock_keys(
std::vector<ExternalDeviceInfo> pixel_unlock_keys) { const std::vector<ExternalDeviceInfo>& pixel_unlock_keys) {
pixel_unlock_keys_ = pixel_unlock_keys; pixel_unlock_keys_ = pixel_unlock_keys;
} }
std::vector<ExternalDeviceInfo>& tether_hosts() { return tether_hosts_; } std::vector<ExternalDeviceInfo>& tether_hosts() { return tether_hosts_; }
void set_tether_hosts(std::vector<ExternalDeviceInfo> tether_hosts) { void set_tether_hosts(const std::vector<ExternalDeviceInfo>& tether_hosts) {
tether_hosts_ = tether_hosts; tether_hosts_ = tether_hosts;
} }
...@@ -57,17 +61,25 @@ class FakeCryptAuthDeviceManager : public CryptAuthDeviceManager { ...@@ -57,17 +61,25 @@ class FakeCryptAuthDeviceManager : public CryptAuthDeviceManager {
} }
void set_pixel_tether_hosts( void set_pixel_tether_hosts(
std::vector<ExternalDeviceInfo> pixel_tether_hosts) { const std::vector<ExternalDeviceInfo>& pixel_tether_hosts) {
pixel_tether_hosts_ = pixel_tether_hosts; pixel_tether_hosts_ = pixel_tether_hosts;
} }
void set_is_recovering_from_failure(bool is_recovering_from_failure) {
is_recovering_from_failure_ = is_recovering_from_failure;
}
void set_is_sync_in_progress(bool is_sync_in_progress) {
is_sync_in_progress_ = is_sync_in_progress;
}
// Finishes the active sync; should only be called if a sync is in progress // Finishes the active sync; should only be called if a sync is in progress
// due to a previous call to ForceSyncNow(). If |sync_result| is SUCCESS, // due to a previous call to ForceSyncNow(). If |sync_result| is SUCCESS,
// |sync_finish_time| will be stored as the last sync time and will be // |sync_finish_time| will be stored as the last sync time and will be
// returned by future calls to GetLastSyncTime(). // returned by future calls to GetLastSyncTime().
void FinishActiveSync(SyncResult sync_result, void FinishActiveSync(SyncResult sync_result,
DeviceChangeResult device_change_result, DeviceChangeResult device_change_result,
const base::Time& sync_finish_time = base::Time()); base::Time sync_finish_time = base::Time());
// Make these functions public for testing. // Make these functions public for testing.
using CryptAuthDeviceManager::NotifySyncStarted; using CryptAuthDeviceManager::NotifySyncStarted;
......
...@@ -16,7 +16,7 @@ void FakeCryptAuthEnrollmentManager::Start() { ...@@ -16,7 +16,7 @@ void FakeCryptAuthEnrollmentManager::Start() {
void FakeCryptAuthEnrollmentManager::FinishActiveEnrollment( void FakeCryptAuthEnrollmentManager::FinishActiveEnrollment(
bool success, bool success,
const base::Time& enrollment_finish_time) { base::Time enrollment_finish_time) {
DCHECK(is_enrollment_in_progress_); DCHECK(is_enrollment_in_progress_);
is_enrollment_in_progress_ = false; is_enrollment_in_progress_ = false;
......
...@@ -21,7 +21,11 @@ class FakeCryptAuthEnrollmentManager : public CryptAuthEnrollmentManager { ...@@ -21,7 +21,11 @@ class FakeCryptAuthEnrollmentManager : public CryptAuthEnrollmentManager {
FakeCryptAuthEnrollmentManager(); FakeCryptAuthEnrollmentManager();
~FakeCryptAuthEnrollmentManager() override; ~FakeCryptAuthEnrollmentManager() override;
void set_time_to_next_attempt(const base::TimeDelta& time_to_next_attempt) { void set_last_enrollment_time(base::Time last_enrollment_time) {
last_enrollment_time_ = last_enrollment_time;
}
void set_time_to_next_attempt(base::TimeDelta time_to_next_attempt) {
time_to_next_attempt_ = time_to_next_attempt; time_to_next_attempt_ = time_to_next_attempt;
} }
...@@ -39,6 +43,14 @@ class FakeCryptAuthEnrollmentManager : public CryptAuthEnrollmentManager { ...@@ -39,6 +43,14 @@ class FakeCryptAuthEnrollmentManager : public CryptAuthEnrollmentManager {
bool has_started() { return has_started_; } bool has_started() { return has_started_; }
void set_is_recovering_from_failure(bool is_recovering_from_failure) {
is_recovering_from_failure_ = is_recovering_from_failure;
}
void set_is_enrollment_in_progress(bool is_enrollment_in_progress) {
is_enrollment_in_progress_ = is_enrollment_in_progress;
}
base::Optional<InvocationReason> last_invocation_reason() { base::Optional<InvocationReason> last_invocation_reason() {
return last_invocation_reason_; return last_invocation_reason_;
} }
...@@ -47,9 +59,8 @@ class FakeCryptAuthEnrollmentManager : public CryptAuthEnrollmentManager { ...@@ -47,9 +59,8 @@ class FakeCryptAuthEnrollmentManager : public CryptAuthEnrollmentManager {
// progress due to a previous call to ForceEnrollmentNow(). If |success| is // progress due to a previous call to ForceEnrollmentNow(). If |success| is
// true, |enrollment_finish_time| will be stored as the last enrollment time // true, |enrollment_finish_time| will be stored as the last enrollment time
// and will be returned by future calls to GetLastEnrollmentTime(). // and will be returned by future calls to GetLastEnrollmentTime().
void FinishActiveEnrollment( void FinishActiveEnrollment(bool success,
bool success, base::Time enrollment_finish_time = base::Time());
const base::Time& enrollment_finish_time = base::Time());
// Make these functions public for testing. // Make these functions public for testing.
using CryptAuthEnrollmentManager::NotifyEnrollmentStarted; using CryptAuthEnrollmentManager::NotifyEnrollmentStarted;
......
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