diff options
author | tengs <tengs@chromium.org> | 2015-07-06 14:24:57 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-06 21:25:49 +0000 |
commit | a23e01d8adf730179274079beae59cbcb7df3e4b (patch) | |
tree | 520f9199ffb0f3d5503480e4e8b3e5f76fd881a7 /components/proximity_auth | |
parent | 71a2bdcce8a90e91d042e0987812adc5bc451242 (diff) | |
download | chromium_src-a23e01d8adf730179274079beae59cbcb7df3e4b.zip chromium_src-a23e01d8adf730179274079beae59cbcb7df3e4b.tar.gz chromium_src-a23e01d8adf730179274079beae59cbcb7df3e4b.tar.bz2 |
Add CryptAuthDeviceManager for syncing the user's devices from CryptAuth.
BUG=420315
TEST=unit test
Review URL: https://codereview.chromium.org/1213203006
Cr-Commit-Position: refs/heads/master@{#337479}
Diffstat (limited to 'components/proximity_auth')
9 files changed, 967 insertions, 13 deletions
diff --git a/components/proximity_auth/cryptauth/BUILD.gn b/components/proximity_auth/cryptauth/BUILD.gn index ddfc973..12e48c8 100644 --- a/components/proximity_auth/cryptauth/BUILD.gn +++ b/components/proximity_auth/cryptauth/BUILD.gn @@ -14,6 +14,8 @@ source_set("cryptauth") { "cryptauth_client.h", "cryptauth_client_impl.cc", "cryptauth_client_impl.h", + "cryptauth_device_manager.cc", + "cryptauth_device_manager.h", "cryptauth_enroller.h", "cryptauth_enroller_impl.cc", "cryptauth_enroller_impl.h", @@ -74,6 +76,7 @@ source_set("unit_tests") { "cryptauth_access_token_fetcher_impl_unittest.cc", "cryptauth_api_call_flow_unittest.cc", "cryptauth_client_impl_unittest.cc", + "cryptauth_device_manager_unittest.cc", "cryptauth_enroller_impl_unittest.cc", "cryptauth_enrollment_manager_unittest.cc", "fake_secure_message_delegate_unittest.cc", diff --git a/components/proximity_auth/cryptauth/cryptauth_device_manager.cc b/components/proximity_auth/cryptauth/cryptauth_device_manager.cc new file mode 100644 index 0000000..709161e --- /dev/null +++ b/components/proximity_auth/cryptauth/cryptauth_device_manager.cc @@ -0,0 +1,257 @@ +// 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 "components/proximity_auth/cryptauth/cryptauth_device_manager.h" + +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_service.h" +#include "base/prefs/scoped_user_pref_update.h" +#include "components/proximity_auth/cryptauth/cryptauth_client.h" +#include "components/proximity_auth/cryptauth/pref_names.h" +#include "components/proximity_auth/cryptauth/sync_scheduler_impl.h" +#include "components/proximity_auth/logging/logging.h" + +namespace proximity_auth { + +namespace { + +// The normal period between successful syncs, in hours. +const int kRefreshPeriodHours = 24; + +// A more aggressive period between sync attempts to recover when the last +// sync attempt fails, in minutes. This is a base time that increases for each +// subsequent failure. +const int kDeviceSyncBaseRecoveryPeriodMinutes = 10; + +// The bound on the amount to jitter the period between syncs. +const double kDeviceSyncMaxJitterRatio = 0.2; + +// Keys for ExternalDeviceInfo dictionaries that are stored in the user's prefs. +const char kExternalDeviceKeyPublicKey[] = "public_key"; +const char kExternalDeviceKeyDeviceName[] = "device_name"; +const char kExternalDeviceKeyBluetoothAddress[] = "bluetooth_address"; + +// Converts an unlock key proto to a dictionary that can be stored in user +// prefs. +scoped_ptr<base::DictionaryValue> UnlockKeyToDictionary( + const cryptauth::ExternalDeviceInfo& device) { + scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue()); + dictionary->SetString(kExternalDeviceKeyPublicKey, device.public_key()); + dictionary->SetString(kExternalDeviceKeyDeviceName, + device.friendly_device_name()); + dictionary->SetString(kExternalDeviceKeyBluetoothAddress, + device.bluetooth_address()); + return dictionary.Pass(); +} + +// Converts an unlock key dictionary stored in user prefs to an +// ExternalDeviceInfo proto. Returns true if the dictionary is valid, and the +// parsed proto is written to |external_device|. +bool DictionaryToUnlockKey(const base::DictionaryValue& dictionary, + cryptauth::ExternalDeviceInfo* external_device) { + std::string public_key, device_name, bluetooth_address; + if (!dictionary.GetString(kExternalDeviceKeyPublicKey, &public_key) || + !dictionary.GetString(kExternalDeviceKeyDeviceName, &device_name) || + !dictionary.GetString(kExternalDeviceKeyBluetoothAddress, + &bluetooth_address)) { + return false; + } + + external_device->set_public_key(public_key); + external_device->set_friendly_device_name(device_name); + external_device->set_bluetooth_address(bluetooth_address); + external_device->set_unlock_key(true); + external_device->set_unlockable(false); + return true; +} + +} // namespace + +CryptAuthDeviceManager::CryptAuthDeviceManager( + scoped_ptr<base::Clock> clock, + scoped_ptr<CryptAuthClientFactory> client_factory, + PrefService* pref_service) + : clock_(clock.Pass()), + client_factory_(client_factory.Pass()), + pref_service_(pref_service), + weak_ptr_factory_(this) { +} + +CryptAuthDeviceManager::~CryptAuthDeviceManager() { +} + +// static +void CryptAuthDeviceManager::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterDoublePref(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds, + 0.0); + registry->RegisterBooleanPref( + prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure, false); + registry->RegisterIntegerPref(prefs::kCryptAuthDeviceSyncReason, + cryptauth::INVOCATION_REASON_UNKNOWN); + registry->RegisterListPref(prefs::kCryptAuthDeviceSyncUnlockKeys); +} + +void CryptAuthDeviceManager::Start() { + UpdateUnlockKeysFromPrefs(); + + base::Time last_successful_sync = GetLastSyncTime(); + base::TimeDelta elapsed_time_since_last_sync = + clock_->Now() - last_successful_sync; + + bool is_recovering_from_failure = + pref_service_->GetBoolean( + prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure) || + last_successful_sync.is_null(); + + scheduler_ = CreateSyncScheduler(); + scheduler_->Start(elapsed_time_since_last_sync, + is_recovering_from_failure + ? SyncScheduler::Strategy::AGGRESSIVE_RECOVERY + : SyncScheduler::Strategy::PERIODIC_REFRESH); +} + +void CryptAuthDeviceManager::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void CryptAuthDeviceManager::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void CryptAuthDeviceManager::ForceSyncNow( + cryptauth::InvocationReason invocation_reason) { + pref_service_->SetInteger(prefs::kCryptAuthDeviceSyncReason, + invocation_reason); + scheduler_->ForceSync(); +} + +base::Time CryptAuthDeviceManager::GetLastSyncTime() const { + return base::Time::FromDoubleT( + pref_service_->GetDouble(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds)); +} + +base::TimeDelta CryptAuthDeviceManager::GetTimeToNextAttempt() const { + return scheduler_->GetTimeToNextSync(); +} + +bool CryptAuthDeviceManager::IsSyncInProgress() const { + return scheduler_->GetSyncState() == + SyncScheduler::SyncState::SYNC_IN_PROGRESS; +} + +bool CryptAuthDeviceManager::IsRecoveringFromFailure() const { + return scheduler_->GetStrategy() == + SyncScheduler::Strategy::AGGRESSIVE_RECOVERY; +} + +void CryptAuthDeviceManager::OnGetMyDevicesSuccess( + const cryptauth::GetMyDevicesResponse& response) { + // Update the unlock keys stored in the user's prefs. + scoped_ptr<base::ListValue> unlock_keys_pref(new base::ListValue()); + for (const auto& device : response.devices()) { + if (device.unlock_key()) + unlock_keys_pref->Append(UnlockKeyToDictionary(device)); + } + + bool unlock_keys_changed = !unlock_keys_pref->Equals( + pref_service_->GetList(prefs::kCryptAuthDeviceSyncUnlockKeys)); + { + ListPrefUpdate update(pref_service_, prefs::kCryptAuthDeviceSyncUnlockKeys); + update.Get()->Swap(unlock_keys_pref.get()); + } + UpdateUnlockKeysFromPrefs(); + + // Reset metadata used for scheduling syncing. + pref_service_->SetBoolean(prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure, + false); + pref_service_->SetDouble(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds, + clock_->Now().ToDoubleT()); + pref_service_->SetInteger(prefs::kCryptAuthDeviceSyncReason, + cryptauth::INVOCATION_REASON_UNKNOWN); + + sync_request_->OnDidComplete(true); + cryptauth_client_.reset(); + sync_request_.reset(); + FOR_EACH_OBSERVER( + Observer, observers_, + OnSyncFinished(SyncResult::SUCCESS, unlock_keys_changed + ? DeviceChangeResult::CHANGED + : DeviceChangeResult::UNCHANGED)); +} + +void CryptAuthDeviceManager::OnGetMyDevicesFailure(const std::string& error) { + PA_LOG(ERROR) << "GetMyDevices API failed: " << error; + pref_service_->SetBoolean(prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure, + true); + sync_request_->OnDidComplete(false); + cryptauth_client_.reset(); + sync_request_.reset(); + FOR_EACH_OBSERVER( + Observer, observers_, + OnSyncFinished(SyncResult::FAILURE, DeviceChangeResult::UNCHANGED)); +} + +scoped_ptr<SyncScheduler> CryptAuthDeviceManager::CreateSyncScheduler() { + return make_scoped_ptr(new SyncSchedulerImpl( + this, base::TimeDelta::FromHours(kRefreshPeriodHours), + base::TimeDelta::FromMinutes(kDeviceSyncBaseRecoveryPeriodMinutes), + kDeviceSyncMaxJitterRatio, "CryptAuth DeviceSync")); +} + +void CryptAuthDeviceManager::UpdateUnlockKeysFromPrefs() { + const base::ListValue* unlock_key_list = + pref_service_->GetList(prefs::kCryptAuthDeviceSyncUnlockKeys); + unlock_keys_.clear(); + for (size_t i = 0; i < unlock_key_list->GetSize(); ++i) { + const base::DictionaryValue* unlock_key_dictionary; + if (unlock_key_list->GetDictionary(i, &unlock_key_dictionary)) { + cryptauth::ExternalDeviceInfo unlock_key; + if (DictionaryToUnlockKey(*unlock_key_dictionary, &unlock_key)) { + unlock_keys_.push_back(unlock_key); + } else { + PA_LOG(ERROR) << "Unable to deserialize unlock key dictionary " + << "(index=" << i << "):\n" << *unlock_key_dictionary; + } + } else { + PA_LOG(ERROR) << "Can not get dictionary in list of unlock keys " + << "(index=" << i << "):\n" << *unlock_key_list; + } + } +} + +void CryptAuthDeviceManager::OnSyncRequested( + scoped_ptr<SyncScheduler::SyncRequest> sync_request) { + FOR_EACH_OBSERVER(Observer, observers_, OnSyncStarted()); + + sync_request_ = sync_request.Pass(); + cryptauth_client_ = client_factory_->CreateInstance(); + + cryptauth::InvocationReason invocation_reason = + cryptauth::INVOCATION_REASON_UNKNOWN; + + int reason_stored_in_prefs = + pref_service_->GetInteger(prefs::kCryptAuthDeviceSyncReason); + + if (cryptauth::InvocationReason_IsValid(reason_stored_in_prefs) && + reason_stored_in_prefs != cryptauth::INVOCATION_REASON_UNKNOWN) { + invocation_reason = + static_cast<cryptauth::InvocationReason>(reason_stored_in_prefs); + } else if (GetLastSyncTime().is_null()) { + invocation_reason = cryptauth::INVOCATION_REASON_INITIALIZATION; + } else if (IsRecoveringFromFailure()) { + invocation_reason = cryptauth::INVOCATION_REASON_FAILURE_RECOVERY; + } else { + invocation_reason = cryptauth::INVOCATION_REASON_PERIODIC; + } + + cryptauth::GetMyDevicesRequest request; + request.set_invocation_reason(invocation_reason); + cryptauth_client_->GetMyDevices( + request, base::Bind(&CryptAuthDeviceManager::OnGetMyDevicesSuccess, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&CryptAuthDeviceManager::OnGetMyDevicesFailure, + weak_ptr_factory_.GetWeakPtr())); +} + +} // namespace proximity_auth diff --git a/components/proximity_auth/cryptauth/cryptauth_device_manager.h b/components/proximity_auth/cryptauth/cryptauth_device_manager.h new file mode 100644 index 0000000..f1dfebe --- /dev/null +++ b/components/proximity_auth/cryptauth/cryptauth_device_manager.h @@ -0,0 +1,157 @@ +// 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. + +#ifndef COMPONENTS_PROXIMITY_AUTH_CRYPTAUTH_CRYPTAUTH_DEVICE_MANAGER_H +#define COMPONENTS_PROXIMITY_AUTH_CRYPTAUTH_CRYPTAUTH_DEVICE_MANAGER_H + +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/time/clock.h" +#include "base/time/time.h" +#include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h" +#include "components/proximity_auth/cryptauth/sync_scheduler.h" + +class PrefService; +class PrefRegistrySimple; + +namespace proximity_auth { + +class CryptAuthClient; +class CryptAuthClientFactory; + +// This class manages syncing and storing the user's phones that are registered +// with CryptAuth and are capable of unlocking the user's other devices. These +// phones are called "unlock keys". +// The manager periodically syncs the user's devices from CryptAuth to keep the +// list of unlock keys fresh. If a sync attempts fails, the manager will +// schedule the next sync more aggressively to recover. +class CryptAuthDeviceManager : public SyncScheduler::Delegate { + public: + // Respresents the success result of a sync attempt. + enum class SyncResult { SUCCESS, FAILURE }; + + // Represents whether the list of unlock keys has changed after a sync + // attempt completes. + enum class DeviceChangeResult { + UNCHANGED, + CHANGED, + }; + + class Observer { + public: + // Called when a sync attempt is started. + virtual void OnSyncStarted() = 0; + + // Called when a sync attempt finishes with the |success| of the request. + // |devices_changed| specifies if the sync caused the stored unlock keys to + // change. + virtual void OnSyncFinished(SyncResult sync_result, + DeviceChangeResult device_change_result) = 0; + + virtual ~Observer() {} + }; + + // Creates the manager: + // |clock|: Used to determine the time between sync attempts. + // |client_factory|: Creates CryptAuthClient instances to perform each sync. + // |pref_service|: Stores syncing metadata and unlock key information to + // persist across browser restarts. Must already be registered + // with RegisterPrefs(). + CryptAuthDeviceManager(scoped_ptr<base::Clock> clock, + scoped_ptr<CryptAuthClientFactory> client_factory, + PrefService* pref_service); + + ~CryptAuthDeviceManager() override; + + // Registers the prefs used by this class to the given |registry|. + static void RegisterPrefs(PrefRegistrySimple* registry); + + // Starts device manager to begin syncing devices. + void Start(); + + // Adds an observer. + void AddObserver(Observer* observer); + + // Removes an observer. + void RemoveObserver(Observer* observer); + + // Skips the waiting period and forces a sync immediately. If a + // sync attempt is already in progress, this function does nothing. + // |invocation_reason| specifies the reason that the sync was triggered, + // which is upload to the server. + void ForceSyncNow(cryptauth::InvocationReason invocation_reason); + + // Returns the timestamp of the last successful sync. If no sync + // has ever been made, then returns a null base::Time object. + base::Time GetLastSyncTime() const; + + // Returns the time to the next sync attempt. + base::TimeDelta GetTimeToNextAttempt() const; + + // Returns true if a device sync attempt is currently in progress. + bool IsSyncInProgress() const; + + // Returns true if the last device sync failed and the manager is now + // scheduling sync attempts more aggressively to recover. If no enrollment + // has ever been recorded, then this function will also return true. + bool IsRecoveringFromFailure() const; + + // Returns a list of remote devices that can unlock the user's other devices. + const std::vector<cryptauth::ExternalDeviceInfo>& unlock_keys() { + return unlock_keys_; + } + + protected: + // Creates a new SyncScheduler instance. Exposed for testing. + virtual scoped_ptr<SyncScheduler> CreateSyncScheduler(); + + private: + // Updates |unlock_keys_| by fetching the list stored in |pref_service_|. + void UpdateUnlockKeysFromPrefs(); + + // SyncScheduler::Delegate: + void OnSyncRequested( + scoped_ptr<SyncScheduler::SyncRequest> sync_request) override; + + // Callback when |cryptauth_client_| completes with the response. + void OnGetMyDevicesSuccess(const cryptauth::GetMyDevicesResponse& response); + void OnGetMyDevicesFailure(const std::string& error); + + // Used to determine the time. + scoped_ptr<base::Clock> clock_; + + // Creates CryptAuthClient instances for each sync attempt. + scoped_ptr<CryptAuthClientFactory> client_factory_; + + // Contains perferences that outlive the lifetime of this object and across + // process restarts. |pref_service_| must outlive the lifetime of this + // instance. + PrefService* const pref_service_; + + // The unlock keys currently synced from CryptAuth. + std::vector<cryptauth::ExternalDeviceInfo> unlock_keys_; + + // Schedules the time between device sync attempts. + scoped_ptr<SyncScheduler> scheduler_; + + // Contains the SyncRequest that |scheduler_| requests when a device sync + // attempt is made. + scoped_ptr<SyncScheduler::SyncRequest> sync_request_; + + // The CryptAuthEnroller instance for the current sync attempt. A new + // instance will be created for each individual attempt. + scoped_ptr<CryptAuthClient> cryptauth_client_; + + // List of observers. + base::ObserverList<Observer> observers_; + + base::WeakPtrFactory<CryptAuthDeviceManager> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CryptAuthDeviceManager); +}; + +} // namespace proximity_auth + +#endif // COMPONENTS_PROXIMITY_CRYPTAUTH_CRYPTAUTH_DEVICE_MANAGER_H diff --git a/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc b/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc new file mode 100644 index 0000000..5574d83 --- /dev/null +++ b/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc @@ -0,0 +1,509 @@ +// 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 "components/proximity_auth/cryptauth/cryptauth_device_manager.h" + +#include "base/memory/weak_ptr.h" +#include "base/prefs/scoped_user_pref_update.h" +#include "base/prefs/testing_pref_service.h" +#include "base/strings/stringprintf.h" +#include "base/test/simple_test_clock.h" +#include "components/proximity_auth/cryptauth/mock_cryptauth_client.h" +#include "components/proximity_auth/cryptauth/mock_sync_scheduler.h" +#include "components/proximity_auth/cryptauth/pref_names.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::DoAll; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::SaveArg; + +namespace proximity_auth { +namespace { + +// The initial "Now" time for testing. +const double kInitialTimeNowSeconds = 20000000; + +// A later "Now" time for testing. +const double kLaterTimeNowSeconds = kInitialTimeNowSeconds + 30; + +// The timestamp of a last successful sync in seconds. +const double kLastSyncTimeSeconds = kInitialTimeNowSeconds - (60 * 60 * 5); + +// Unlock key fields originally stored in the user prefs. +const char kStoredPublicKey[] = "AAPL"; +const char kStoredDeviceName[] = "iPhone 6"; +const char kStoredBluetoothAddress[] = "12:34:56:78:90:AB"; + +// ExternalDeviceInfo fields for the synced unlock key. +const char kPublicKey1[] = "GOOG"; +const char kDeviceName1[] = "Nexus 5"; +const char kBluetoothAddress1[] = "aa:bb:cc:ee:dd:ff"; + +// ExternalDeviceInfo fields for a non-synced unlockable device. +const char kPublicKey2[] = "MSFT"; +const char kDeviceName2[] = "Surface Pro 3"; + +// Validates that |unlock_keys| and the corresponding preferences stored by +// |pref_service| are equal to |expected_unlock_keys|. +void ExpectUnlockKeysAndPrefAreEqual( + const std::vector<cryptauth::ExternalDeviceInfo>& expected_unlock_keys, + const std::vector<cryptauth::ExternalDeviceInfo>& unlock_keys, + const PrefService& pref_service) { + ASSERT_EQ(expected_unlock_keys.size(), unlock_keys.size()); + for (size_t i = 0; i < unlock_keys.size(); ++i) { + SCOPED_TRACE( + base::StringPrintf("Compare protos at index=%d", static_cast<int>(i))); + const auto& expected_unlock_key = expected_unlock_keys[i]; + const auto& unlock_key = unlock_keys.at(i); + EXPECT_EQ(expected_unlock_key.public_key(), unlock_key.public_key()); + EXPECT_EQ(expected_unlock_key.friendly_device_name(), + unlock_key.friendly_device_name()); + EXPECT_EQ(expected_unlock_key.bluetooth_address(), + unlock_key.bluetooth_address()); + EXPECT_TRUE(expected_unlock_key.unlock_key()); + EXPECT_FALSE(expected_unlock_key.unlockable()); + } + + const base::ListValue* unlock_keys_pref = + pref_service.GetList(prefs::kCryptAuthDeviceSyncUnlockKeys); + ASSERT_EQ(expected_unlock_keys.size(), unlock_keys_pref->GetSize()); + for (size_t i = 0; i < unlock_keys_pref->GetSize(); ++i) { + SCOPED_TRACE(base::StringPrintf("Compare pref dictionary at index=%d", + static_cast<int>(i))); + const base::DictionaryValue* unlock_key_dictionary; + EXPECT_TRUE(unlock_keys_pref->GetDictionary(i, &unlock_key_dictionary)); + std::string public_key, device_name, bluetooth_address; + EXPECT_TRUE(unlock_key_dictionary->GetString("public_key", &public_key)); + EXPECT_TRUE(unlock_key_dictionary->GetString("device_name", &device_name)); + EXPECT_TRUE(unlock_key_dictionary->GetString("bluetooth_address", + &bluetooth_address)); + + const auto& expected_unlock_key = expected_unlock_keys[i]; + EXPECT_EQ(expected_unlock_key.public_key(), public_key); + EXPECT_EQ(expected_unlock_key.friendly_device_name(), device_name); + EXPECT_EQ(expected_unlock_key.bluetooth_address(), bluetooth_address); + EXPECT_TRUE(expected_unlock_key.unlock_key()); + EXPECT_FALSE(expected_unlock_key.unlockable()); + } +} + +// Harness for testing CryptAuthDeviceManager. +class TestCryptAuthDeviceManager : public CryptAuthDeviceManager { + public: + TestCryptAuthDeviceManager(scoped_ptr<base::Clock> clock, + scoped_ptr<CryptAuthClientFactory> client_factory, + PrefService* pref_service) + : CryptAuthDeviceManager(clock.Pass(), + client_factory.Pass(), + pref_service), + scoped_sync_scheduler_(new NiceMock<MockSyncScheduler>()), + weak_sync_scheduler_factory_(scoped_sync_scheduler_.get()) {} + + ~TestCryptAuthDeviceManager() override {} + + scoped_ptr<SyncScheduler> CreateSyncScheduler() override { + EXPECT_TRUE(scoped_sync_scheduler_); + return scoped_sync_scheduler_.Pass(); + } + + base::WeakPtr<MockSyncScheduler> GetSyncScheduler() { + return weak_sync_scheduler_factory_.GetWeakPtr(); + } + + private: + // Ownership is passed to |CryptAuthDeviceManager| super class when + // |CreateSyncScheduler()| is called. + scoped_ptr<MockSyncScheduler> scoped_sync_scheduler_; + + // Stores the pointer of |scoped_sync_scheduler_| after ownership is passed to + // the super class. + // This should be safe because the life-time this SyncScheduler will always be + // within the life of the TestCryptAuthDeviceManager object. + base::WeakPtrFactory<MockSyncScheduler> weak_sync_scheduler_factory_; + + DISALLOW_COPY_AND_ASSIGN(TestCryptAuthDeviceManager); +}; + +} // namespace + +class ProximityAuthCryptAuthDeviceManagerTest + : public testing::Test, + public CryptAuthDeviceManager::Observer, + public MockCryptAuthClientFactory::Observer { + protected: + ProximityAuthCryptAuthDeviceManagerTest() + : clock_(new base::SimpleTestClock()), + client_factory_(new MockCryptAuthClientFactory( + MockCryptAuthClientFactory::MockType::MAKE_STRICT_MOCKS)), + device_manager_(make_scoped_ptr(clock_), + make_scoped_ptr(client_factory_), + &pref_service_) { + client_factory_->AddObserver(this); + } + + ~ProximityAuthCryptAuthDeviceManagerTest() { + client_factory_->RemoveObserver(this); + } + + // testing::Test: + void SetUp() override { + clock_->SetNow(base::Time::FromDoubleT(kInitialTimeNowSeconds)); + device_manager_.AddObserver(this); + + CryptAuthDeviceManager::RegisterPrefs(pref_service_.registry()); + pref_service_.SetUserPref( + prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure, + new base::FundamentalValue(false)); + pref_service_.SetUserPref(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds, + new base::FundamentalValue(kLastSyncTimeSeconds)); + pref_service_.SetUserPref( + prefs::kCryptAuthDeviceSyncReason, + new base::FundamentalValue(cryptauth::INVOCATION_REASON_UNKNOWN)); + + scoped_ptr<base::DictionaryValue> unlock_key_dictionary( + new base::DictionaryValue()); + unlock_key_dictionary->SetString("public_key", kStoredPublicKey); + unlock_key_dictionary->SetString("device_name", kStoredDeviceName); + unlock_key_dictionary->SetString("bluetooth_address", + kStoredBluetoothAddress); + { + ListPrefUpdate update(&pref_service_, + prefs::kCryptAuthDeviceSyncUnlockKeys); + update.Get()->Append(unlock_key_dictionary.Pass()); + } + + cryptauth::ExternalDeviceInfo unlock_key; + unlock_key.set_public_key(kPublicKey1); + unlock_key.set_friendly_device_name(kDeviceName1); + unlock_key.set_bluetooth_address(kBluetoothAddress1); + unlock_key.set_unlock_key(true); + unlock_key.set_unlockable(false); + + cryptauth::ExternalDeviceInfo unlockable_device; + unlockable_device.set_public_key(kPublicKey2); + unlockable_device.set_friendly_device_name(kDeviceName2); + unlockable_device.set_unlock_key(false); + unlockable_device.set_unlockable(true); + + get_my_devices_response_.add_devices()->CopyFrom(unlock_key); + get_my_devices_response_.add_devices()->CopyFrom(unlockable_device); + + ON_CALL(*sync_scheduler(), GetStrategy()) + .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH)); + } + + void TearDown() override { device_manager_.RemoveObserver(this); } + + // CryptAuthDeviceManager::Observer: + void OnSyncStarted() override { OnSyncStartedProxy(); } + + void OnSyncFinished(CryptAuthDeviceManager::SyncResult sync_result, + CryptAuthDeviceManager::DeviceChangeResult + device_change_result) override { + OnSyncFinishedProxy(sync_result, device_change_result); + } + + MOCK_METHOD0(OnSyncStartedProxy, void()); + MOCK_METHOD2(OnSyncFinishedProxy, + void(CryptAuthDeviceManager::SyncResult, + CryptAuthDeviceManager::DeviceChangeResult)); + + // Simulates firing the SyncScheduler to trigger a device sync attempt. + void FireSchedulerForSync( + cryptauth::InvocationReason expected_invocation_reason) { + SyncScheduler::Delegate* delegate = + static_cast<SyncScheduler::Delegate*>(&device_manager_); + + scoped_ptr<SyncScheduler::SyncRequest> sync_request = make_scoped_ptr( + new SyncScheduler::SyncRequest(device_manager_.GetSyncScheduler())); + EXPECT_CALL(*this, OnSyncStartedProxy()); + delegate->OnSyncRequested(sync_request.Pass()); + + EXPECT_EQ(expected_invocation_reason, + get_my_devices_request_.invocation_reason()); + } + + // MockCryptAuthClientFactory::Observer: + void OnCryptAuthClientCreated(MockCryptAuthClient* client) override { + EXPECT_CALL(*client, GetMyDevices(_, _, _)) + .WillOnce(DoAll(SaveArg<0>(&get_my_devices_request_), + SaveArg<1>(&success_callback_), + SaveArg<2>(&error_callback_))); + } + + MockSyncScheduler* sync_scheduler() { + return device_manager_.GetSyncScheduler().get(); + } + + // Owned by |device_manager_|. + base::SimpleTestClock* clock_; + + // Owned by |device_manager_|. + MockCryptAuthClientFactory* client_factory_; + + TestingPrefServiceSimple pref_service_; + + TestCryptAuthDeviceManager device_manager_; + + cryptauth::GetMyDevicesResponse get_my_devices_response_; + + cryptauth::GetMyDevicesRequest get_my_devices_request_; + + CryptAuthClient::GetMyDevicesCallback success_callback_; + + CryptAuthClient::ErrorCallback error_callback_; + + DISALLOW_COPY_AND_ASSIGN(ProximityAuthCryptAuthDeviceManagerTest); +}; + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, RegisterPrefs) { + TestingPrefServiceSimple pref_service; + CryptAuthDeviceManager::RegisterPrefs(pref_service.registry()); + EXPECT_TRUE(pref_service.FindPreference( + prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds)); + EXPECT_TRUE(pref_service.FindPreference( + prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); + EXPECT_TRUE(pref_service.FindPreference(prefs::kCryptAuthDeviceSyncReason)); + EXPECT_TRUE( + pref_service.FindPreference(prefs::kCryptAuthDeviceSyncUnlockKeys)); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, GetSyncState) { + device_manager_.Start(); + + ON_CALL(*sync_scheduler(), GetStrategy()) + .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH)); + EXPECT_FALSE(device_manager_.IsRecoveringFromFailure()); + + ON_CALL(*sync_scheduler(), GetStrategy()) + .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY)); + EXPECT_TRUE(device_manager_.IsRecoveringFromFailure()); + + base::TimeDelta time_to_next_sync = base::TimeDelta::FromMinutes(60); + ON_CALL(*sync_scheduler(), GetTimeToNextSync()) + .WillByDefault(Return(time_to_next_sync)); + EXPECT_EQ(time_to_next_sync, device_manager_.GetTimeToNextAttempt()); + + ON_CALL(*sync_scheduler(), GetSyncState()) + .WillByDefault(Return(SyncScheduler::SyncState::SYNC_IN_PROGRESS)); + EXPECT_TRUE(device_manager_.IsSyncInProgress()); + + ON_CALL(*sync_scheduler(), GetSyncState()) + .WillByDefault(Return(SyncScheduler::SyncState::WAITING_FOR_REFRESH)); + EXPECT_FALSE(device_manager_.IsSyncInProgress()); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, InitWithDefaultPrefs) { + scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock); + clock->SetNow(base::Time::FromDoubleT(kInitialTimeNowSeconds)); + base::TimeDelta elapsed_time = clock->Now() - base::Time::FromDoubleT(0); + + TestingPrefServiceSimple pref_service; + CryptAuthDeviceManager::RegisterPrefs(pref_service.registry()); + + TestCryptAuthDeviceManager device_manager( + clock.Pass(), + make_scoped_ptr(new MockCryptAuthClientFactory( + MockCryptAuthClientFactory::MockType::MAKE_STRICT_MOCKS)), + &pref_service); + + EXPECT_CALL( + *(device_manager.GetSyncScheduler()), + Start(elapsed_time, SyncScheduler::Strategy::AGGRESSIVE_RECOVERY)); + device_manager.Start(); + EXPECT_TRUE(device_manager.GetLastSyncTime().is_null()); + EXPECT_EQ(0u, device_manager.unlock_keys().size()); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, InitWithExistingPrefs) { + EXPECT_CALL( + *sync_scheduler(), + Start(clock_->Now() - base::Time::FromDoubleT(kLastSyncTimeSeconds), + SyncScheduler::Strategy::PERIODIC_REFRESH)); + + device_manager_.Start(); + EXPECT_EQ(base::Time::FromDoubleT(kLastSyncTimeSeconds), + device_manager_.GetLastSyncTime()); + + auto unlock_keys = device_manager_.unlock_keys(); + ASSERT_EQ(1u, unlock_keys.size()); + EXPECT_EQ(kStoredPublicKey, unlock_keys[0].public_key()); + EXPECT_EQ(kStoredDeviceName, unlock_keys[0].friendly_device_name()); + EXPECT_EQ(kStoredBluetoothAddress, unlock_keys[0].bluetooth_address()); + EXPECT_TRUE(unlock_keys[0].unlock_key()); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncSucceedsForFirstTime) { + pref_service_.ClearPref(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds); + device_manager_.Start(); + + FireSchedulerForSync(cryptauth::INVOCATION_REASON_INITIALIZATION); + ASSERT_FALSE(success_callback_.is_null()); + + clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds)); + EXPECT_CALL(*this, OnSyncFinishedProxy( + CryptAuthDeviceManager::SyncResult::SUCCESS, + CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); + + success_callback_.Run(get_my_devices_response_); + EXPECT_EQ(clock_->Now(), device_manager_.GetLastSyncTime()); + + ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>( + 1, get_my_devices_response_.devices(0)), + device_manager_.unlock_keys(), pref_service_); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, ForceSync) { + device_manager_.Start(); + + EXPECT_CALL(*sync_scheduler(), ForceSync()); + device_manager_.ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL); + + FireSchedulerForSync(cryptauth::INVOCATION_REASON_MANUAL); + + clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds)); + EXPECT_CALL(*this, OnSyncFinishedProxy( + CryptAuthDeviceManager::SyncResult::SUCCESS, + CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); + success_callback_.Run(get_my_devices_response_); + EXPECT_EQ(clock_->Now(), device_manager_.GetLastSyncTime()); + + ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>( + 1, get_my_devices_response_.devices(0)), + device_manager_.unlock_keys(), pref_service_); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, ForceSyncFailsThenSucceeds) { + device_manager_.Start(); + EXPECT_FALSE(pref_service_.GetBoolean( + prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); + base::Time old_sync_time = device_manager_.GetLastSyncTime(); + + // The first force sync fails. + EXPECT_CALL(*sync_scheduler(), ForceSync()); + device_manager_.ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL); + FireSchedulerForSync(cryptauth::INVOCATION_REASON_MANUAL); + clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds)); + EXPECT_CALL(*this, + OnSyncFinishedProxy( + CryptAuthDeviceManager::SyncResult::FAILURE, + CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED)); + error_callback_.Run("404"); + EXPECT_EQ(old_sync_time, device_manager_.GetLastSyncTime()); + EXPECT_TRUE(pref_service_.GetBoolean( + prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); + EXPECT_EQ(static_cast<int>(cryptauth::INVOCATION_REASON_MANUAL), + pref_service_.GetInteger(prefs::kCryptAuthDeviceSyncReason)); + + // The second recovery sync succeeds. + ON_CALL(*sync_scheduler(), GetStrategy()) + .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY)); + FireSchedulerForSync(cryptauth::INVOCATION_REASON_MANUAL); + clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds + 30)); + EXPECT_CALL(*this, OnSyncFinishedProxy( + CryptAuthDeviceManager::SyncResult::SUCCESS, + CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); + success_callback_.Run(get_my_devices_response_); + EXPECT_EQ(clock_->Now(), device_manager_.GetLastSyncTime()); + + ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>( + 1, get_my_devices_response_.devices(0)), + device_manager_.unlock_keys(), pref_service_); + + EXPECT_FLOAT_EQ( + clock_->Now().ToDoubleT(), + pref_service_.GetDouble(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds)); + EXPECT_EQ(static_cast<int>(cryptauth::INVOCATION_REASON_UNKNOWN), + pref_service_.GetInteger(prefs::kCryptAuthDeviceSyncReason)); + EXPECT_FALSE(pref_service_.GetBoolean( + prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncSameDevice) { + // Set the same unlock key in the user prefs as the one that would be synced. + { + scoped_ptr<base::DictionaryValue> unlock_key_dictionary( + new base::DictionaryValue()); + unlock_key_dictionary->SetString("public_key", kPublicKey1); + unlock_key_dictionary->SetString("device_name", kDeviceName1); + unlock_key_dictionary->SetString("bluetooth_address", kBluetoothAddress1); + + ListPrefUpdate update(&pref_service_, + prefs::kCryptAuthDeviceSyncUnlockKeys); + update.Get()->Clear(); + update.Get()->Append(unlock_key_dictionary.Pass()); + } + + // Check unlock keys before sync. + device_manager_.Start(); + auto original_unlock_keys = device_manager_.unlock_keys(); + ASSERT_EQ(1u, original_unlock_keys.size()); + EXPECT_EQ(kPublicKey1, original_unlock_keys[0].public_key()); + EXPECT_EQ(kDeviceName1, original_unlock_keys[0].friendly_device_name()); + EXPECT_EQ(kBluetoothAddress1, original_unlock_keys[0].bluetooth_address()); + + // Sync new devices. + FireSchedulerForSync(cryptauth::INVOCATION_REASON_PERIODIC); + ASSERT_FALSE(success_callback_.is_null()); + EXPECT_CALL(*this, + OnSyncFinishedProxy( + CryptAuthDeviceManager::SyncResult::SUCCESS, + CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED)); + success_callback_.Run(get_my_devices_response_); + + // Check that unlock keys are still the same after sync. + ExpectUnlockKeysAndPrefAreEqual(original_unlock_keys, + device_manager_.unlock_keys(), pref_service_); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncEmptyDeviceList) { + cryptauth::GetMyDevicesResponse empty_response; + + device_manager_.Start(); + EXPECT_EQ(1u, device_manager_.unlock_keys().size()); + + FireSchedulerForSync(cryptauth::INVOCATION_REASON_PERIODIC); + ASSERT_FALSE(success_callback_.is_null()); + EXPECT_CALL(*this, OnSyncFinishedProxy( + CryptAuthDeviceManager::SyncResult::SUCCESS, + CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); + success_callback_.Run(empty_response); + + ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>(), + device_manager_.unlock_keys(), pref_service_); +} + +TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncTwoUnlockKeys) { + cryptauth::GetMyDevicesResponse response(get_my_devices_response_); + cryptauth::ExternalDeviceInfo unlock_key2; + unlock_key2.set_public_key("new public key"); + unlock_key2.set_friendly_device_name("new device name"); + unlock_key2.set_bluetooth_address("aa:bb:cc:dd:ee:ff"); + unlock_key2.set_unlock_key(true); + response.add_devices()->CopyFrom(unlock_key2); + + std::vector<cryptauth::ExternalDeviceInfo> expected_unlock_keys; + expected_unlock_keys.push_back(get_my_devices_response_.devices(0)); + expected_unlock_keys.push_back(unlock_key2); + + device_manager_.Start(); + EXPECT_EQ(1u, device_manager_.unlock_keys().size()); + EXPECT_EQ(1u, pref_service_.GetList(prefs::kCryptAuthDeviceSyncUnlockKeys) + ->GetSize()); + + FireSchedulerForSync(cryptauth::INVOCATION_REASON_PERIODIC); + ASSERT_FALSE(success_callback_.is_null()); + EXPECT_CALL(*this, OnSyncFinishedProxy( + CryptAuthDeviceManager::SyncResult::SUCCESS, + CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); + success_callback_.Run(response); + + ExpectUnlockKeysAndPrefAreEqual(expected_unlock_keys, + device_manager_.unlock_keys(), pref_service_); +} + +} // namespace proximity_auth diff --git a/components/proximity_auth/cryptauth/cryptauth_enroller_impl_unittest.cc b/components/proximity_auth/cryptauth/cryptauth_enroller_impl_unittest.cc index 9ab0dfb..ec369aa 100644 --- a/components/proximity_auth/cryptauth/cryptauth_enroller_impl_unittest.cc +++ b/components/proximity_auth/cryptauth/cryptauth_enroller_impl_unittest.cc @@ -101,7 +101,8 @@ class ProximityAuthCryptAuthEnrollerTest public MockCryptAuthClientFactory::Observer { public: ProximityAuthCryptAuthEnrollerTest() - : client_factory_(new MockCryptAuthClientFactory(false)), + : client_factory_(new MockCryptAuthClientFactory( + MockCryptAuthClientFactory::MockType::MAKE_NICE_MOCKS)), secure_message_delegate_(new FakeSecureMessageDelegate()), enroller_(make_scoped_ptr(client_factory_), make_scoped_ptr(secure_message_delegate_)) { diff --git a/components/proximity_auth/cryptauth/mock_cryptauth_client.cc b/components/proximity_auth/cryptauth/mock_cryptauth_client.cc index 5566f9e..834fd74 100644 --- a/components/proximity_auth/cryptauth/mock_cryptauth_client.cc +++ b/components/proximity_auth/cryptauth/mock_cryptauth_client.cc @@ -14,8 +14,8 @@ MockCryptAuthClient::MockCryptAuthClient() { MockCryptAuthClient::~MockCryptAuthClient() { } -MockCryptAuthClientFactory::MockCryptAuthClientFactory(bool is_strict) - : is_strict_(is_strict) { +MockCryptAuthClientFactory::MockCryptAuthClientFactory(MockType mock_type) + : mock_type_(mock_type) { } MockCryptAuthClientFactory::~MockCryptAuthClientFactory() { @@ -23,7 +23,7 @@ MockCryptAuthClientFactory::~MockCryptAuthClientFactory() { scoped_ptr<CryptAuthClient> MockCryptAuthClientFactory::CreateInstance() { scoped_ptr<MockCryptAuthClient> client; - if (is_strict_) + if (mock_type_ == MockType::MAKE_STRICT_MOCKS) client.reset(new testing::StrictMock<MockCryptAuthClient>()); else client.reset(new testing::NiceMock<MockCryptAuthClient>()); diff --git a/components/proximity_auth/cryptauth/mock_cryptauth_client.h b/components/proximity_auth/cryptauth/mock_cryptauth_client.h index adf2129..27bfd13 100644 --- a/components/proximity_auth/cryptauth/mock_cryptauth_client.h +++ b/components/proximity_auth/cryptauth/mock_cryptauth_client.h @@ -58,9 +58,12 @@ class MockCryptAuthClientFactory : public CryptAuthClientFactory { virtual void OnCryptAuthClientCreated(MockCryptAuthClient* client) = 0; }; - // If |is_strict| is true, then StrictMocks will be created. Otherwise, + // Represents the type of mock instances to create. + enum class MockType { MAKE_NICE_MOCKS, MAKE_STRICT_MOCKS }; + + // If |mock_type| is STRICT, then StrictMocks will be created. Otherwise, // NiceMocks will be created. - explicit MockCryptAuthClientFactory(bool is_strict); + explicit MockCryptAuthClientFactory(MockType mock_type); ~MockCryptAuthClientFactory() override; // CryptAuthClientFactory: @@ -71,7 +74,7 @@ class MockCryptAuthClientFactory : public CryptAuthClientFactory { private: // Whether to create StrictMocks or NiceMocks. - bool is_strict_; + const MockType mock_type_; // Observers of the factory. base::ObserverList<Observer> observer_list_; diff --git a/components/proximity_auth/cryptauth/pref_names.cc b/components/proximity_auth/cryptauth/pref_names.cc index 81ff279..db06a2f 100644 --- a/components/proximity_auth/cryptauth/pref_names.cc +++ b/components/proximity_auth/cryptauth/pref_names.cc @@ -7,19 +7,39 @@ namespace proximity_auth { namespace prefs { -// The timestamp of the last successfull CryptAuth enrollment in seconds. -const char kCryptAuthEnrollmentLastEnrollmentTimeSeconds[] = - "cryptauth.enrollment.last_enrollment_time_seconds"; +// Whether the system is scheduling device_syncs more aggressively to recover +// from the previous device_sync failure. +const char kCryptAuthDeviceSyncIsRecoveringFromFailure[] = + "cryptauth.device_sync.is_recovering_from_failure"; -// The reason that the next enrollment is performed. This should be one of the +// The timestamp of the last successfull CryptAuth device_sync in seconds. +const char kCryptAuthDeviceSyncLastSyncTimeSeconds[] = + "cryptauth.device_sync.last_device_sync_time_seconds"; + +// The reason that the next device_sync is performed. This should be one of the // enum values of InvocationReason in // components/proximity_auth/cryptauth/proto/cryptauth_api.proto. -extern const char kCryptAuthEnrollmentReason[] = "cryptauth.enrollment.reason"; +const char kCryptAuthDeviceSyncReason[] = "cryptauth.device_sync.reason"; + +// A list of unlock keys (stored as dictionaries) synced from CryptAuth. Unlock +// Keys are phones belonging to the user that can unlock other devices, such as +// desktop PCs. +const char kCryptAuthDeviceSyncUnlockKeys[] = + "cryptauth.device_sync.unlock_keys"; // Whether the system is scheduling enrollments more aggressively to recover // from the previous enrollment failure. const char kCryptAuthEnrollmentIsRecoveringFromFailure[] = "cryptauth.enrollment.is_recovering_from_failure"; +// The timestamp of the last successfull CryptAuth enrollment in seconds. +const char kCryptAuthEnrollmentLastEnrollmentTimeSeconds[] = + "cryptauth.enrollment.last_enrollment_time_seconds"; + +// The reason that the next enrollment is performed. This should be one of the +// enum values of InvocationReason in +// components/proximity_auth/cryptauth/proto/cryptauth_api.proto. +extern const char kCryptAuthEnrollmentReason[] = "cryptauth.enrollment.reason"; + } // namespace prefs } // proximity_auth diff --git a/components/proximity_auth/cryptauth/pref_names.h b/components/proximity_auth/cryptauth/pref_names.h index 48de7f7..2caa187 100644 --- a/components/proximity_auth/cryptauth/pref_names.h +++ b/components/proximity_auth/cryptauth/pref_names.h @@ -8,9 +8,13 @@ namespace proximity_auth { namespace prefs { +extern const char kCryptAuthDeviceSyncLastSyncTimeSeconds[]; +extern const char kCryptAuthDeviceSyncIsRecoveringFromFailure[]; +extern const char kCryptAuthDeviceSyncReason[]; +extern const char kCryptAuthDeviceSyncUnlockKeys[]; +extern const char kCryptAuthEnrollmentIsRecoveringFromFailure[]; extern const char kCryptAuthEnrollmentLastEnrollmentTimeSeconds[]; extern const char kCryptAuthEnrollmentReason[]; -extern const char kCryptAuthEnrollmentIsRecoveringFromFailure[]; } // namespace prefs } // proximity_auth |