Commit 256fbf85 authored by Ryan Hansberry's avatar Ryan Hansberry Committed by Commit Bot

[CrOS Multidevice] Make EasyUnlockServiceRegular conditionally use DeviceSyncClient.

EasyUnlockServiceRegular now uses either CryptAuthService or DeviceSyncClient
to get remote device info or perform Cryptauth calls, depending on whether the
chromeos::features::kMultiDeviceApi is enabled. Once the migration to DeviceSyncClient
has been completed across all of Smart Lock, code that references CryptAuthService will
be removed.

This is the last of other similar CLs which are migrating Smart Lock to use
DeviceSync Mojo API instead of directly using the CryptAuth API.

This CL also injects DeviceSyncClient into EasyUnlockServiceRegular, making Smart Lock
rely entirely on DeviceSyncClient if chromeos::features::kMultiDeviceApi is enabled.
I have manually verified that it works correctly by testing the following:

1. Setting up Smart Lock.
2. Using Smart Lock in the regular lock-screen manner.
3. Using Smart Lock in the login-screen manner.
4. Ensuring that notifications display at the correct time.
5. Turning off Smart Lock.
6. Ensuring that permits are correctly saved to prefs (the new model can't
   use the old way of grabbing the user's AccountId).

TBR=jhawkins@chromium.org

Bug: 824568, 752273, 848956
Change-Id: I3acc6dec46ff1ddc2875fbfe97261bb195a9494b
Reviewed-on: https://chromium-review.googlesource.com/1102164
Commit-Queue: Ryan Hansberry <hansberry@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567769}
parent 97f4fb9b
......@@ -64,7 +64,8 @@ constexpr char kInvalidPassword[] = "invalid";
class FakeEasyUnlockService : public EasyUnlockServiceRegular {
public:
explicit FakeEasyUnlockService(Profile* profile)
: EasyUnlockServiceRegular(profile), reauth_count_(0) {}
: EasyUnlockServiceRegular(profile, nullptr /* device_sync_client */),
reauth_count_(0) {}
~FakeEasyUnlockService() override {}
// EasyUnlockServiceRegular:
......
......@@ -8,6 +8,7 @@
#include "base/memory/singleton.h"
#include "build/build_config.h"
#include "chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.h"
#include "chrome/browser/chromeos/device_sync/device_sync_client_factory.h"
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_app_manager.h"
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.h"
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.h"
......@@ -68,6 +69,7 @@ EasyUnlockServiceFactory::EasyUnlockServiceFactory()
DependsOn(
extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
DependsOn(EasyUnlockTpmKeyManagerFactory::GetInstance());
DependsOn(device_sync::DeviceSyncClientFactory::GetInstance());
}
EasyUnlockServiceFactory::~EasyUnlockServiceFactory() {}
......@@ -90,8 +92,10 @@ KeyedService* EasyUnlockServiceFactory::BuildServiceInstanceFor(
}
if (!service) {
service =
new EasyUnlockServiceRegular(Profile::FromBrowserContext(context));
service = new EasyUnlockServiceRegular(
Profile::FromBrowserContext(context),
device_sync::DeviceSyncClientFactory::GetForProfile(
Profile::FromBrowserContext(context)));
manifest_id = IDR_EASY_UNLOCK_MANIFEST;
}
......
......@@ -37,6 +37,7 @@
#include "chrome/common/extensions/api/easy_unlock_private.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "chromeos/chromeos_features.h"
#include "chromeos/components/proximity_auth/logging/logging.h"
#include "chromeos/components/proximity_auth/proximity_auth_pref_names.h"
#include "chromeos/components/proximity_auth/proximity_auth_profile_pref_manager.h"
......@@ -104,14 +105,18 @@ void LogSmartLockEnabledState(SmartLockEnabledState state) {
} // namespace
EasyUnlockServiceRegular::EasyUnlockServiceRegular(Profile* profile)
EasyUnlockServiceRegular::EasyUnlockServiceRegular(
Profile* profile,
device_sync::DeviceSyncClient* device_sync_client)
: EasyUnlockServiceRegular(
profile,
std::make_unique<EasyUnlockNotificationController>(profile)) {}
std::make_unique<EasyUnlockNotificationController>(profile),
device_sync_client) {}
EasyUnlockServiceRegular::EasyUnlockServiceRegular(
Profile* profile,
std::unique_ptr<EasyUnlockNotificationController> notification_controller)
std::unique_ptr<EasyUnlockNotificationController> notification_controller,
device_sync::DeviceSyncClient* device_sync_client)
: EasyUnlockService(profile),
turn_off_flow_status_(EasyUnlockService::IDLE),
scoped_crypt_auth_device_manager_observer_(this),
......@@ -119,18 +124,43 @@ EasyUnlockServiceRegular::EasyUnlockServiceRegular(
lock_screen_last_shown_timestamp_(base::TimeTicks::Now()),
deferring_device_load_(false),
notification_controller_(std::move(notification_controller)),
device_sync_client_(device_sync_client),
shown_pairing_changed_notification_(false),
weak_ptr_factory_(this) {}
weak_ptr_factory_(this) {
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
// If this is the first GetSyncedDevices() call on DeviceSyncClient, it
// won't have devices cached yet. |is_waiting_for_initial_sync_| is flipped
// to indicate that we are waiting for this initial sync, to be inspected
// in OnNewDevicesSynced(). OnNewDevicesSynced() needs to know that it is
// receiving the initial sync, not a newly forced one, in order to prevent
// it from running unrelated logic.
if (device_sync_client_->GetSyncedDevices().empty())
is_waiting_for_initial_sync_ = true;
else
remote_device_unlock_keys_before_sync_ = GetUnlockKeys();
device_sync_client_->AddObserver(this);
}
}
EasyUnlockServiceRegular::~EasyUnlockServiceRegular() {
registrar_.RemoveAll();
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi))
device_sync_client_->RemoveObserver(this);
}
// TODO(jhawkins): This method with |has_unlock_keys| == true is the only signal
// that SmartLock setup has completed successfully. Make this signal more
// explicit.
void EasyUnlockServiceRegular::LoadRemoteDevices() {
bool has_unlock_keys = !GetCryptAuthDeviceManager()->GetUnlockKeys().empty();
bool has_unlock_keys;
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
has_unlock_keys = !GetUnlockKeys().empty();
} else {
has_unlock_keys = !GetCryptAuthDeviceManager()->GetUnlockKeys().empty();
}
// TODO(jhawkins): The enabled pref should not be tied to whether unlock keys
// exist; instead, both of these variables should be used to determine
// IsEnabled().
......@@ -162,31 +192,45 @@ void EasyUnlockServiceRegular::LoadRemoteDevices() {
return;
}
remote_device_loader_.reset(new cryptauth::RemoteDeviceLoader(
GetCryptAuthDeviceManager()->GetUnlockKeys(),
proximity_auth_client()->GetAccountId(),
GetCryptAuthEnrollmentManager()->GetUserPrivateKey(),
cryptauth::SecureMessageDelegateImpl::Factory::NewInstance()));
remote_device_loader_->Load(
base::Bind(&EasyUnlockServiceRegular::OnRemoteDevicesLoaded,
weak_ptr_factory_.GetWeakPtr()));
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
UseLoadedRemoteDevices(GetUnlockKeys());
} else {
remote_device_loader_.reset(new cryptauth::RemoteDeviceLoader(
GetCryptAuthDeviceManager()->GetUnlockKeys(),
proximity_auth_client()->GetAccountId(),
GetCryptAuthEnrollmentManager()->GetUserPrivateKey(),
cryptauth::SecureMessageDelegateImpl::Factory::NewInstance()));
// OnRemoteDevicesLoaded() will call on UseLoadedRemoteDevices() with the
// devices it receives.
remote_device_loader_->Load(
base::Bind(&EasyUnlockServiceRegular::OnRemoteDevicesLoaded,
weak_ptr_factory_.GetWeakPtr()));
}
}
void EasyUnlockServiceRegular::OnRemoteDevicesLoaded(
const cryptauth::RemoteDeviceList& remote_devices) {
DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
cryptauth::RemoteDeviceRefList remote_device_refs;
for (auto& remote_device : remote_devices) {
remote_device_refs.push_back(cryptauth::RemoteDeviceRef(
std::make_shared<cryptauth::RemoteDevice>(remote_device)));
}
SetProximityAuthDevices(GetAccountId(), remote_device_refs);
UseLoadedRemoteDevices(remote_device_refs);
}
void EasyUnlockServiceRegular::UseLoadedRemoteDevices(
const cryptauth::RemoteDeviceRefList& remote_devices) {
SetProximityAuthDevices(GetAccountId(), remote_devices);
// We need to store a copy of |remote devices_| in the TPM, so it can be
// retrieved on the sign-in screen when a user session has not been started
// yet.
std::unique_ptr<base::ListValue> device_list(new base::ListValue());
for (const auto& device : remote_device_refs) {
for (const auto& device : remote_devices) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
std::string b64_public_key, b64_psk;
base::Base64UrlEncode(device.public_key(),
......@@ -198,10 +242,19 @@ void EasyUnlockServiceRegular::OnRemoteDevicesLoaded(
dict->SetString("name", device.name());
dict->SetString("psk", b64_psk);
// TODO(jhawkins): Remove the bluetoothAddress field from this proto.
dict->SetString("bluetoothAddress", std::string());
dict->SetString("permitId", "permit://google.com/easyunlock/v1/" +
proximity_auth_client()->GetAccountId());
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
dict->SetString("permitId", "permit://google.com/easyunlock/v1/" +
gaia::CanonicalizeEmail(
GetAccountId().GetUserEmail()));
} else {
dict->SetString("permitId", "permit://google.com/easyunlock/v1/" +
proximity_auth_client()->GetAccountId());
}
dict->SetString("permitRecord.id", b64_public_key);
dict->SetString("permitRecord.type", "license");
dict->SetString("permitRecord.data", b64_public_key);
......@@ -347,25 +400,36 @@ void EasyUnlockServiceRegular::SetRemoteDevices(
void EasyUnlockServiceRegular::RunTurnOffFlow() {
if (turn_off_flow_status_ == PENDING)
return;
DCHECK(!cryptauth_client_);
LogToggleFeature(SmartLockToggleFeature::DISABLE);
SetTurnOffFlowStatus(PENDING);
std::unique_ptr<cryptauth::CryptAuthClientFactory> factory =
proximity_auth_client()->CreateCryptAuthClientFactory();
cryptauth_client_ = factory->CreateInstance();
cryptauth::ToggleEasyUnlockRequest request;
request.set_enable(false);
request.set_apply_to_all(true);
cryptauth_client_->ToggleEasyUnlock(
request,
base::Bind(&EasyUnlockServiceRegular::OnToggleEasyUnlockApiComplete,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&EasyUnlockServiceRegular::OnToggleEasyUnlockApiFailed,
weak_ptr_factory_.GetWeakPtr()));
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
// Disabling EASY_UNLOCK_HOST is a special case that does not require a
// public key to be passed; EASY_UNLOCK_HOST will be disabled for all hosts.
device_sync_client_->SetSoftwareFeatureState(
std::string() /* public_key */,
cryptauth::SoftwareFeature::EASY_UNLOCK_HOST, false /* enabled */,
false /* is_exclusive */,
base::BindOnce(&EasyUnlockServiceRegular::OnTurnOffEasyUnlockCompleted,
weak_ptr_factory_.GetWeakPtr()));
} else {
DCHECK(!cryptauth_client_);
std::unique_ptr<cryptauth::CryptAuthClientFactory> factory =
proximity_auth_client()->CreateCryptAuthClientFactory();
cryptauth_client_ = factory->CreateInstance();
cryptauth::ToggleEasyUnlockRequest request;
request.set_enable(false);
request.set_apply_to_all(true);
cryptauth_client_->ToggleEasyUnlock(
request,
base::Bind(&EasyUnlockServiceRegular::OnToggleEasyUnlockApiComplete,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&EasyUnlockServiceRegular::OnToggleEasyUnlockApiFailed,
weak_ptr_factory_.GetWeakPtr()));
}
}
void EasyUnlockServiceRegular::ResetTurnOffFlow() {
......@@ -412,7 +476,13 @@ void EasyUnlockServiceRegular::InitializeInternal() {
GetAccountId());
}
scoped_crypt_auth_device_manager_observer_.Add(GetCryptAuthDeviceManager());
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
remote_device_unlock_keys_before_sync_ = GetUnlockKeys();
} else {
scoped_crypt_auth_device_manager_observer_.Add(
GetCryptAuthDeviceManager());
}
LoadRemoteDevices();
}
......@@ -428,7 +498,11 @@ void EasyUnlockServiceRegular::ShutdownInternal() {
turn_off_flow_status_ = EasyUnlockService::IDLE;
proximity_auth::ScreenlockBridge::Get()->RemoveObserver(this);
scoped_crypt_auth_device_manager_observer_.RemoveAll();
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi))
device_sync_client_->RemoveObserver(this);
else
scoped_crypt_auth_device_manager_observer_.RemoveAll();
}
bool EasyUnlockServiceRegular::IsAllowedInternal() const {
......@@ -475,6 +549,8 @@ void EasyUnlockServiceRegular::OnSyncFinished(
cryptauth::CryptAuthDeviceManager::SyncResult sync_result,
cryptauth::CryptAuthDeviceManager::DeviceChangeResult
device_change_result) {
DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
if (sync_result == cryptauth::CryptAuthDeviceManager::SyncResult::FAILURE)
return;
......@@ -491,6 +567,47 @@ void EasyUnlockServiceRegular::OnSyncFinished(
public_keys_after_sync.insert(device_info.public_key());
}
ShowNotificationIfNewDevicePresent(public_keys_before_sync,
public_keys_after_sync);
LoadRemoteDevices();
}
void EasyUnlockServiceRegular::OnNewDevicesSynced() {
// This method copies EasyUnlockServiceRegular::OnSyncFinished().
// TODO(crbug.com/848956): Remove EasyUnlockServiceRegular::OnSyncFinished().
DCHECK(base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
std::set<std::string> public_keys_before_sync;
if (is_waiting_for_initial_sync_) {
is_waiting_for_initial_sync_ = false;
// Without this, |public_keys_before_sync| would be incorrectly empty.
remote_device_unlock_keys_before_sync_ = GetUnlockKeys();
}
for (const auto& remote_device : remote_device_unlock_keys_before_sync_) {
public_keys_before_sync.insert(remote_device.public_key());
}
cryptauth::RemoteDeviceRefList remote_device_unlock_keys_after_sync =
GetUnlockKeys();
std::set<std::string> public_keys_after_sync;
for (const auto& remote_device : remote_device_unlock_keys_after_sync) {
public_keys_after_sync.insert(remote_device.public_key());
}
ShowNotificationIfNewDevicePresent(public_keys_before_sync,
public_keys_after_sync);
LoadRemoteDevices();
remote_device_unlock_keys_before_sync_ = remote_device_unlock_keys_after_sync;
}
void EasyUnlockServiceRegular::ShowNotificationIfNewDevicePresent(
const std::set<std::string>& public_keys_before_sync,
const std::set<std::string>& public_keys_after_sync) {
if (public_keys_after_sync.empty())
ClearPermitAccess();
......@@ -504,16 +621,19 @@ void EasyUnlockServiceRegular::OnSyncFinished(
bool is_setup_fresh =
short_lived_user_context_ && short_lived_user_context_->user_context();
if (public_keys_after_sync.size() > 0 && !is_setup_fresh) {
if (public_keys_before_sync.size() == 0) {
if (!public_keys_after_sync.empty() && !is_setup_fresh) {
if (public_keys_before_sync.empty()) {
notification_controller_->ShowChromebookAddedNotification();
} else {
shown_pairing_changed_notification_ = true;
notification_controller_->ShowPairingChangeNotification();
}
}
}
LoadRemoteDevices();
void EasyUnlockServiceRegular::OnForceSyncCompleted(bool success) {
if (!success)
PA_LOG(WARNING) << "Failed to force device sync.";
}
void EasyUnlockServiceRegular::OnScreenDidLock(
......@@ -592,23 +712,51 @@ void EasyUnlockServiceRegular::SetTurnOffFlowStatus(TurnOffFlowStatus status) {
void EasyUnlockServiceRegular::OnToggleEasyUnlockApiComplete(
const cryptauth::ToggleEasyUnlockResponse& response) {
DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
cryptauth_client_.reset();
OnTurnOffEasyUnlockSuccess();
}
void EasyUnlockServiceRegular::OnToggleEasyUnlockApiFailed(
const std::string& error_message) {
DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
OnTurnOffEasyUnlockFailure(error_message);
}
void EasyUnlockServiceRegular::OnTurnOffEasyUnlockCompleted(
const base::Optional<std::string>& error_code) {
DCHECK(base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
if (error_code)
OnTurnOffEasyUnlockFailure(*error_code);
else
OnTurnOffEasyUnlockSuccess();
}
void EasyUnlockServiceRegular::OnTurnOffEasyUnlockSuccess() {
PA_LOG(INFO) << "Successfully turned off Smart Lock.";
LogToggleFeatureDisableResult(SmartLockResult::SUCCESS);
cryptauth_client_.reset();
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
remote_device_unlock_keys_before_sync_ = GetUnlockKeys();
device_sync_client_->ForceSyncNow(
base::BindOnce(&EasyUnlockServiceRegular::OnForceSyncCompleted,
weak_ptr_factory_.GetWeakPtr()));
} else {
GetCryptAuthDeviceManager()->ForceSyncNow(
cryptauth::InvocationReason::INVOCATION_REASON_FEATURE_TOGGLED);
}
GetCryptAuthDeviceManager()->ForceSyncNow(
cryptauth::InvocationReason::INVOCATION_REASON_FEATURE_TOGGLED);
EasyUnlockService::ResetLocalStateForUser(GetAccountId());
SetRemoteDevices(base::ListValue());
SetProximityAuthDevices(GetAccountId(), cryptauth::RemoteDeviceRefList());
pref_manager_->SetIsEasyUnlockEnabled(false);
SetTurnOffFlowStatus(IDLE);
pref_manager_->SetIsEasyUnlockEnabled(false);
ResetScreenlockState();
registrar_.RemoveAll();
}
void EasyUnlockServiceRegular::OnToggleEasyUnlockApiFailed(
void EasyUnlockServiceRegular::OnTurnOffEasyUnlockFailure(
const std::string& error_message) {
LOG(WARNING) << "Failed to turn off Smart Lock: " << error_message;
LogToggleFeatureDisableResult(SmartLockResult::FAILURE);
......@@ -617,6 +765,8 @@ void EasyUnlockServiceRegular::OnToggleEasyUnlockApiFailed(
cryptauth::CryptAuthEnrollmentManager*
EasyUnlockServiceRegular::GetCryptAuthEnrollmentManager() {
DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
cryptauth::CryptAuthEnrollmentManager* manager =
ChromeCryptAuthServiceFactory::GetInstance()
->GetForBrowserContext(profile())
......@@ -627,6 +777,8 @@ EasyUnlockServiceRegular::GetCryptAuthEnrollmentManager() {
cryptauth::CryptAuthDeviceManager*
EasyUnlockServiceRegular::GetCryptAuthDeviceManager() {
DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
cryptauth::CryptAuthDeviceManager* manager =
ChromeCryptAuthServiceFactory::GetInstance()
->GetForBrowserContext(profile())
......@@ -657,4 +809,13 @@ void EasyUnlockServiceRegular::RefreshCryptohomeKeysIfPossible() {
}
}
cryptauth::RemoteDeviceRefList EasyUnlockServiceRegular::GetUnlockKeys() {
cryptauth::RemoteDeviceRefList unlock_keys;
for (const auto& remote_device : device_sync_client_->GetSyncedDevices()) {
if (remote_device.unlock_key())
unlock_keys.push_back(remote_device);
}
return unlock_keys;
}
} // namespace chromeos
......@@ -10,13 +10,16 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.h"
#include "chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.h"
#include "chromeos/components/proximity_auth/screenlock_bridge.h"
#include "chromeos/services/device_sync/public/cpp/device_sync_client.h"
#include "components/cryptauth/cryptauth_device_manager.h"
#include "components/cryptauth/remote_device_ref.h"
#include "components/prefs/pref_change_registrar.h"
namespace base {
......@@ -47,14 +50,18 @@ class EasyUnlockNotificationController;
class EasyUnlockServiceRegular
: public EasyUnlockService,
public proximity_auth::ScreenlockBridge::Observer,
public cryptauth::CryptAuthDeviceManager::Observer {
public cryptauth::CryptAuthDeviceManager::Observer,
public device_sync::DeviceSyncClient::Observer {
public:
explicit EasyUnlockServiceRegular(Profile* profile);
explicit EasyUnlockServiceRegular(
Profile* profile,
device_sync::DeviceSyncClient* device_sync_client);
// Constructor for tests.
EasyUnlockServiceRegular(Profile* profile,
std::unique_ptr<EasyUnlockNotificationController>
notification_controller);
EasyUnlockServiceRegular(
Profile* profile,
std::unique_ptr<EasyUnlockNotificationController> notification_controller,
device_sync::DeviceSyncClient* device_sync_client);
~EasyUnlockServiceRegular() override;
......@@ -66,6 +73,9 @@ class EasyUnlockServiceRegular
// Called when |remote_device_loader_| completes.
void OnRemoteDevicesLoaded(const cryptauth::RemoteDeviceList& remote_devices);
void UseLoadedRemoteDevices(
const cryptauth::RemoteDeviceRefList& remote_devices);
// EasyUnlockService implementation:
proximity_auth::ProximityAuthPrefManager* GetProximityAuthPrefManager()
override;
......@@ -98,6 +108,15 @@ class EasyUnlockServiceRegular
cryptauth::CryptAuthDeviceManager::DeviceChangeResult
device_change_result) override;
// device_sync::DeviceSyncClient::Observer:
void OnNewDevicesSynced() override;
void ShowNotificationIfNewDevicePresent(
const std::set<std::string>& public_keys_before_sync,
const std::set<std::string>& public_keys_after_sync);
void OnForceSyncCompleted(bool success);
// proximity_auth::ScreenlockBridge::Observer implementation:
void OnScreenDidLock(proximity_auth::ScreenlockBridge::LockHandler::ScreenType
screen_type) override;
......@@ -114,6 +133,12 @@ class EasyUnlockServiceRegular
const cryptauth::ToggleEasyUnlockResponse& response);
void OnToggleEasyUnlockApiFailed(const std::string& error_message);
void OnTurnOffEasyUnlockCompleted(
const base::Optional<std::string>& error_code);
void OnTurnOffEasyUnlockSuccess();
void OnTurnOffEasyUnlockFailure(const std::string& error_message);
// Called with the user's credentials (e.g. username and password) after the
// user reauthenticates to begin setup.
void OpenSetupAppAfterReauth(const UserContext& user_context);
......@@ -138,6 +163,8 @@ class EasyUnlockServiceRegular
// Otherwise, hardlock the device.
void RefreshCryptohomeKeysIfPossible();
cryptauth::RemoteDeviceRefList GetUnlockKeys();
TurnOffFlowStatus turn_off_flow_status_;
std::unique_ptr<cryptauth::CryptAuthClient> cryptauth_client_;
ScopedObserver<cryptauth::CryptAuthDeviceManager, EasyUnlockServiceRegular>
......@@ -174,15 +201,26 @@ class EasyUnlockServiceRegular
// Responsible for showing all the notifications used for EasyUnlock.
std::unique_ptr<EasyUnlockNotificationController> notification_controller_;
device_sync::DeviceSyncClient* device_sync_client_;
// Stores the unlock keys for EasyUnlock before the current device sync, so we
// can compare it to the unlock keys after syncing.
std::vector<cryptauth::ExternalDeviceInfo> unlock_keys_before_sync_;
cryptauth::RemoteDeviceRefList remote_device_unlock_keys_before_sync_;
// True if the pairing changed notification was shown, so that the next time
// the Chromebook is unlocked, we can show the subsequent 'pairing applied'
// notification.
bool shown_pairing_changed_notification_;
// If this service is the first caller on DeviceSyncClient, it won't have
// devices cached yet. |is_waiting_for_initial_sync_| is set to true if
// DeviceSyncClient has no devices, to indicate that we are waiting for the
// initial sync, to be inspected in OnNewDevicesSynced(). OnNewDevicesSynced()
// needs to know that it is receiving the initial sync, not a newly forced
// one, in order to prevent it from running unrelated logic.
bool is_waiting_for_initial_sync_ = false;
// Listens to pref changes.
PrefChangeRegistrar registrar_;
......
......@@ -29,6 +29,7 @@
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/power_manager/suspend.pb.h"
#include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h"
#include "components/account_id/account_id.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
......@@ -44,6 +45,7 @@ using testing::AnyNumber;
using testing::Return;
namespace chromeos {
namespace {
// IDs for fake users used in tests.
......@@ -181,10 +183,15 @@ class TestAppManagerFactory {
DISALLOW_COPY_AND_ASSIGN(TestAppManagerFactory);
};
// Global TestAppManager factory. It should be created and desctructed in
// EasyUnlockServiceTest::SetUp and EasyUnlockServiceTest::TearDown
// Global TestAppManager factory. It should be created and destroyed in
// EasyUnlockServiceTest::SetUp and EasyUnlockServiceTest::TearDown,
// respectively.
TestAppManagerFactory* app_manager_factory = nullptr;
// Global FakeDeviceSyncClient. It should be created and destroyed in
// EasyUnlockServiceTest::SetUp and EasyUnlockServiceTest::TearDown,
// respectively.
TestAppManagerFactory* app_manager_factory = NULL;
device_sync::FakeDeviceSyncClient* fake_device_sync_client = nullptr;
// EasyUnlockService factory function injected into testing profiles.
// It creates an EasyUnlockService with test AppManager.
......@@ -203,13 +210,16 @@ std::unique_ptr<KeyedService> CreateEasyUnlockServiceForTest(
std::unique_ptr<EasyUnlockServiceRegular> service(
new EasyUnlockServiceRegular(
Profile::FromBrowserContext(context),
std::make_unique<MockEasyUnlockNotificationController>()));
std::make_unique<MockEasyUnlockNotificationController>(),
fake_device_sync_client));
service->Initialize(std::move(app_manager));
return std::move(service);
}
} // namespace
class EasyUnlockServiceTest : public testing::Test {
public:
protected:
EasyUnlockServiceTest()
: mock_user_manager_(new testing::NiceMock<MockUserManager>()),
scoped_user_manager_(base::WrapUnique(mock_user_manager_)),
......@@ -219,6 +229,7 @@ class EasyUnlockServiceTest : public testing::Test {
void SetUp() override {
app_manager_factory = new TestAppManagerFactory();
fake_device_sync_client = new device_sync::FakeDeviceSyncClient();
mock_adapter_ = new testing::NiceMock<MockBluetoothAdapter>();
device::BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_);
......@@ -247,8 +258,12 @@ class EasyUnlockServiceTest : public testing::Test {
void TearDown() override {
TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);
delete app_manager_factory;
app_manager_factory = NULL;
app_manager_factory = nullptr;
delete fake_device_sync_client;
fake_device_sync_client = nullptr;
}
void SetEasyUnlockAllowedPolicy(bool allowed) {
......@@ -286,13 +301,6 @@ class EasyUnlockServiceTest : public testing::Test {
app_manager->SetReady();
}
void SetUpSecondaryProfile() {
SetUpProfile(
&secondary_profile_,
AccountId::FromUserEmailGaiaId(kTestUserSecondary, kSecondaryGaiaId));
}
private:
// Sets up a test profile with a user id.
void SetUpProfile(std::unique_ptr<TestingProfile>* profile,
const AccountId& account_id) {
......@@ -313,11 +321,15 @@ class EasyUnlockServiceTest : public testing::Test {
account_id.GetUserEmail());
}
private:
void SetUpSecondaryProfile() {
SetUpProfile(
&secondary_profile_,
AccountId::FromUserEmailGaiaId(kTestUserSecondary, kSecondaryGaiaId));
}
// Must outlive TestingProfiles.
content::TestBrowserThreadBundle thread_bundle_;
protected:
std::unique_ptr<TestingProfile> profile_;
std::unique_ptr<TestingProfile> secondary_profile_;
MockUserManager* mock_user_manager_;
......@@ -413,5 +425,4 @@ TEST_F(EasyUnlockServiceTest, GetAccountId) {
EasyUnlockService::Get(secondary_profile_.get())->GetAccountId());
}
} // namespace
} // 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