| // Copyright 2014 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 "chrome/browser/signin/easy_unlock_service_regular.h" |
| |
| #include <stdint.h> |
| |
| #include <utility> |
| |
| #include "base/base64url.h" |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/logging.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/sys_info.h" |
| #include "base/time/default_clock.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/cryptauth/chrome_cryptauth_service_factory.h" |
| #include "chrome/browser/gcm/gcm_profile_service_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/signin/chrome_proximity_auth_client.h" |
| #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| #include "chrome/browser/signin/signin_manager_factory.h" |
| #include "chrome/common/extensions/api/easy_unlock_private.h" |
| #include "chrome/common/extensions/extension_constants.h" |
| #include "chrome/common/pref_names.h" |
| #include "components/cryptauth/cryptauth_access_token_fetcher.h" |
| #include "components/cryptauth/cryptauth_client_impl.h" |
| #include "components/cryptauth/cryptauth_enrollment_manager.h" |
| #include "components/cryptauth/cryptauth_enrollment_utils.h" |
| #include "components/cryptauth/cryptauth_gcm_manager_impl.h" |
| #include "components/cryptauth/remote_device_loader.h" |
| #include "components/cryptauth/secure_message_delegate.h" |
| #include "components/gcm_driver/gcm_profile_service.h" |
| #include "components/pref_registry/pref_registry_syncable.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/prefs/scoped_user_pref_update.h" |
| #include "components/proximity_auth/logging/logging.h" |
| #include "components/proximity_auth/proximity_auth_pref_manager.h" |
| #include "components/proximity_auth/proximity_auth_system.h" |
| #include "components/proximity_auth/screenlock_bridge.h" |
| #include "components/proximity_auth/switches.h" |
| #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| #include "components/signin/core/browser/signin_manager.h" |
| #include "components/translate/core/browser/translate_download_manager.h" |
| #include "components/version_info/version_info.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "extensions/browser/event_router.h" |
| #include "extensions/common/constants.h" |
| #include "google_apis/gaia/gaia_auth_util.h" |
| |
| #if defined(OS_CHROMEOS) |
| #include "apps/app_lifetime_monitor_factory.h" |
| #include "ash/shell.h" |
| #include "base/linux_util.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h" |
| #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.h" |
| #include "chrome/browser/chromeos/login/session/user_session_manager.h" |
| #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| #include "components/user_manager/user_manager.h" |
| #include "ui/display/manager/display_manager.h" |
| #include "ui/display/manager/managed_display_info.h" |
| #endif |
| |
| namespace { |
| |
| // Key name of the local device permit record dictonary in kEasyUnlockPairing. |
| const char kKeyPermitAccess[] = "permitAccess"; |
| |
| // Key name of the remote device list in kEasyUnlockPairing. |
| const char kKeyDevices[] = "devices"; |
| |
| } // namespace |
| |
| EasyUnlockServiceRegular::EasyUnlockServiceRegular(Profile* profile) |
| : EasyUnlockService(profile), |
| turn_off_flow_status_(EasyUnlockService::IDLE), |
| will_unlock_using_easy_unlock_(false), |
| lock_screen_last_shown_timestamp_(base::TimeTicks::Now()), |
| deferring_device_load_(false), |
| weak_ptr_factory_(this) {} |
| |
| EasyUnlockServiceRegular::~EasyUnlockServiceRegular() { |
| } |
| |
| proximity_auth::ProximityAuthPrefManager* |
| EasyUnlockServiceRegular::GetProximityAuthPrefManager() { |
| return pref_manager_.get(); |
| } |
| |
| void EasyUnlockServiceRegular::LoadRemoteDevices() { |
| if (GetCryptAuthDeviceManager()->GetUnlockKeys().empty()) { |
| SetProximityAuthDevices(GetAccountId(), cryptauth::RemoteDeviceList()); |
| return; |
| } |
| |
| remote_device_loader_.reset(new cryptauth::RemoteDeviceLoader( |
| GetCryptAuthDeviceManager()->GetUnlockKeys(), |
| proximity_auth_client()->GetAccountId(), |
| GetCryptAuthEnrollmentManager()->GetUserPrivateKey(), |
| proximity_auth_client()->CreateSecureMessageDelegate())); |
| remote_device_loader_->Load( |
| base::Bind(&EasyUnlockServiceRegular::OnRemoteDevicesLoaded, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| void EasyUnlockServiceRegular::OnRemoteDevicesLoaded( |
| const cryptauth::RemoteDeviceList& remote_devices) { |
| SetProximityAuthDevices(GetAccountId(), remote_devices); |
| |
| #if defined(OS_CHROMEOS) |
| // 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_devices) { |
| std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| std::string b64_public_key, b64_psk; |
| base::Base64UrlEncode(device.public_key, |
| base::Base64UrlEncodePolicy::INCLUDE_PADDING, |
| &b64_public_key); |
| base::Base64UrlEncode(device.persistent_symmetric_key, |
| base::Base64UrlEncodePolicy::INCLUDE_PADDING, |
| &b64_psk); |
| |
| dict->SetString("name", device.name); |
| dict->SetString("psk", b64_psk); |
| dict->SetString("bluetoothAddress", device.bluetooth_address); |
| 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); |
| device_list->Append(std::move(dict)); |
| } |
| |
| // TODO(tengs): Rename this function after the easy_unlock app is replaced. |
| SetRemoteDevices(*device_list); |
| #endif |
| } |
| |
| EasyUnlockService::Type EasyUnlockServiceRegular::GetType() const { |
| return EasyUnlockService::TYPE_REGULAR; |
| } |
| |
| AccountId EasyUnlockServiceRegular::GetAccountId() const { |
| const SigninManagerBase* signin_manager = |
| SigninManagerFactory::GetForProfileIfExists(profile()); |
| // |profile| has to be a signed-in profile with SigninManager already |
| // created. Otherwise, just crash to collect stack. |
| DCHECK(signin_manager); |
| const AccountInfo account_info = |
| signin_manager->GetAuthenticatedAccountInfo(); |
| return account_info.email.empty() |
| ? EmptyAccountId() |
| : AccountId::FromUserEmailGaiaId( |
| gaia::CanonicalizeEmail(account_info.email), |
| account_info.gaia); |
| } |
| |
| void EasyUnlockServiceRegular::LaunchSetup() { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| #if defined(OS_CHROMEOS) |
| // Force the user to reauthenticate by showing a modal overlay (similar to the |
| // lock screen). The password obtained from the reauth is cached for a short |
| // period of time and used to create the cryptohome keys for sign-in. |
| if (short_lived_user_context_ && short_lived_user_context_->user_context()) { |
| OpenSetupApp(); |
| } else { |
| bool reauth_success = chromeos::EasyUnlockReauth::ReauthForUserContext( |
| base::Bind(&EasyUnlockServiceRegular::OnUserContextFromReauth, |
| weak_ptr_factory_.GetWeakPtr())); |
| if (!reauth_success) |
| OpenSetupApp(); |
| } |
| #else |
| OpenSetupApp(); |
| #endif |
| } |
| |
| #if defined(OS_CHROMEOS) |
| void EasyUnlockServiceRegular::OnUserContextFromReauth( |
| const chromeos::UserContext& user_context) { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| short_lived_user_context_.reset(new chromeos::ShortLivedUserContext( |
| user_context, |
| apps::AppLifetimeMonitorFactory::GetForBrowserContext(profile()), |
| base::ThreadTaskRunnerHandle::Get().get())); |
| |
| OpenSetupApp(); |
| |
| // Use this opportunity to clear the crytohome keys if it was not already |
| // cleared earlier. |
| const base::ListValue* devices = GetRemoteDevices(); |
| if (!devices || devices->empty()) { |
| chromeos::EasyUnlockKeyManager* key_manager = |
| chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager(); |
| key_manager->RefreshKeys( |
| user_context, base::ListValue(), |
| base::Bind(&EasyUnlockServiceRegular::SetHardlockAfterKeyOperation, |
| weak_ptr_factory_.GetWeakPtr(), |
| EasyUnlockScreenlockStateHandler::NO_PAIRING)); |
| } |
| } |
| |
| void EasyUnlockServiceRegular::SetHardlockAfterKeyOperation( |
| EasyUnlockScreenlockStateHandler::HardlockState state_on_success, |
| bool success) { |
| if (success) |
| SetHardlockStateForUser(GetAccountId(), state_on_success); |
| |
| // Even if the refresh keys operation suceeded, we still fetch and check the |
| // cryptohome keys against the keys in local preferences as a sanity check. |
| CheckCryptohomeKeysAndMaybeHardlock(); |
| } |
| #endif |
| |
| const base::DictionaryValue* EasyUnlockServiceRegular::GetPermitAccess() const { |
| const base::DictionaryValue* pairing_dict = |
| profile()->GetPrefs()->GetDictionary(prefs::kEasyUnlockPairing); |
| const base::DictionaryValue* permit_dict = NULL; |
| if (pairing_dict && |
| pairing_dict->GetDictionary(kKeyPermitAccess, &permit_dict)) |
| return permit_dict; |
| |
| return NULL; |
| } |
| |
| void EasyUnlockServiceRegular::SetPermitAccess( |
| const base::DictionaryValue& permit) { |
| DictionaryPrefUpdate pairing_update(profile()->GetPrefs(), |
| prefs::kEasyUnlockPairing); |
| pairing_update->SetWithoutPathExpansion(kKeyPermitAccess, permit.DeepCopy()); |
| } |
| |
| void EasyUnlockServiceRegular::ClearPermitAccess() { |
| DictionaryPrefUpdate pairing_update(profile()->GetPrefs(), |
| prefs::kEasyUnlockPairing); |
| pairing_update->RemoveWithoutPathExpansion(kKeyPermitAccess, NULL); |
| } |
| |
| const base::ListValue* EasyUnlockServiceRegular::GetRemoteDevices() const { |
| const base::DictionaryValue* pairing_dict = |
| profile()->GetPrefs()->GetDictionary(prefs::kEasyUnlockPairing); |
| const base::ListValue* devices = NULL; |
| if (pairing_dict && pairing_dict->GetList(kKeyDevices, &devices)) |
| return devices; |
| return NULL; |
| } |
| |
| void EasyUnlockServiceRegular::SetRemoteDevices( |
| const base::ListValue& devices) { |
| DictionaryPrefUpdate pairing_update(profile()->GetPrefs(), |
| prefs::kEasyUnlockPairing); |
| if (devices.empty()) |
| pairing_update->RemoveWithoutPathExpansion(kKeyDevices, NULL); |
| else |
| pairing_update->SetWithoutPathExpansion(kKeyDevices, devices.DeepCopy()); |
| |
| #if defined(OS_CHROMEOS) |
| // TODO(tengs): Investigate if we can determine if the remote devices were set |
| // from sync or from the setup app. |
| if (short_lived_user_context_ && short_lived_user_context_->user_context()) { |
| // We may already have the password cached, so proceed to create the |
| // cryptohome keys for sign-in or the system will be hardlocked. |
| chromeos::UserSessionManager::GetInstance() |
| ->GetEasyUnlockKeyManager() |
| ->RefreshKeys( |
| *short_lived_user_context_->user_context(), devices, |
| base::Bind(&EasyUnlockServiceRegular::SetHardlockAfterKeyOperation, |
| weak_ptr_factory_.GetWeakPtr(), |
| EasyUnlockScreenlockStateHandler::NO_HARDLOCK)); |
| } else { |
| CheckCryptohomeKeysAndMaybeHardlock(); |
| } |
| #else |
| CheckCryptohomeKeysAndMaybeHardlock(); |
| #endif |
| } |
| |
| // This method is called from easyUnlock.setRemoteDevice JS API. It's used |
| // here to set the (public key, device address) pair for BLE devices. |
| void EasyUnlockServiceRegular::SetRemoteBleDevices( |
| const base::ListValue& devices) { |
| DCHECK(devices.GetSize() == 1); |
| const base::DictionaryValue* dict = nullptr; |
| if (devices.GetDictionary(0, &dict)) { |
| std::string address, b64_public_key; |
| if (dict->GetString("bluetoothAddress", &address) && |
| dict->GetString("psk", &b64_public_key)) { |
| GetProximityAuthPrefManager()->AddOrUpdateDevice(address, b64_public_key); |
| |
| // The setup is done. Load the remote devices if the device with |
| // |public_key| was already sync from CryptAuth, otherwise re-sync the |
| // devices. |
| if (GetCryptAuthDeviceManager()) { |
| std::string public_key; |
| if (!base::Base64UrlDecode(b64_public_key, |
| base::Base64UrlDecodePolicy::REQUIRE_PADDING, |
| &public_key)) { |
| PA_LOG(ERROR) << "Unable to base64url decode the public key: " |
| << b64_public_key; |
| return; |
| } |
| const std::vector<cryptauth::ExternalDeviceInfo> unlock_keys = |
| GetCryptAuthDeviceManager()->GetUnlockKeys(); |
| auto iterator = std::find_if( |
| unlock_keys.begin(), unlock_keys.end(), |
| [&public_key](const cryptauth::ExternalDeviceInfo& unlock_key) { |
| return unlock_key.public_key() == public_key; |
| }); |
| |
| if (iterator != unlock_keys.end()) { |
| LoadRemoteDevices(); |
| } else { |
| GetCryptAuthDeviceManager()->ForceSyncNow( |
| cryptauth::INVOCATION_REASON_FEATURE_TOGGLED); |
| } |
| } |
| } else { |
| PA_LOG(ERROR) << "Missing public key or device address"; |
| } |
| } |
| } |
| |
| void EasyUnlockServiceRegular::RunTurnOffFlow() { |
| if (turn_off_flow_status_ == PENDING) |
| return; |
| DCHECK(!cryptauth_client_); |
| |
| 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())); |
| } |
| |
| void EasyUnlockServiceRegular::ResetTurnOffFlow() { |
| cryptauth_client_.reset(); |
| SetTurnOffFlowStatus(IDLE); |
| } |
| |
| EasyUnlockService::TurnOffFlowStatus |
| EasyUnlockServiceRegular::GetTurnOffFlowStatus() const { |
| return turn_off_flow_status_; |
| } |
| |
| std::string EasyUnlockServiceRegular::GetChallenge() const { |
| return std::string(); |
| } |
| |
| std::string EasyUnlockServiceRegular::GetWrappedSecret() const { |
| return std::string(); |
| } |
| |
| void EasyUnlockServiceRegular::RecordEasySignInOutcome( |
| const AccountId& account_id, |
| bool success) const { |
| NOTREACHED(); |
| } |
| |
| void EasyUnlockServiceRegular::RecordPasswordLoginEvent( |
| const AccountId& account_id) const { |
| NOTREACHED(); |
| } |
| |
| void EasyUnlockServiceRegular::StartAutoPairing( |
| const AutoPairingResultCallback& callback) { |
| if (!auto_pairing_callback_.is_null()) { |
| LOG(ERROR) |
| << "Start auto pairing when there is another auto pairing requested."; |
| callback.Run(false, std::string()); |
| return; |
| } |
| |
| auto_pairing_callback_ = callback; |
| |
| std::unique_ptr<base::ListValue> args(new base::ListValue()); |
| std::unique_ptr<extensions::Event> event(new extensions::Event( |
| extensions::events::EASY_UNLOCK_PRIVATE_ON_START_AUTO_PAIRING, |
| extensions::api::easy_unlock_private::OnStartAutoPairing::kEventName, |
| std::move(args))); |
| extensions::EventRouter::Get(profile())->DispatchEventWithLazyListener( |
| extension_misc::kEasyUnlockAppId, std::move(event)); |
| } |
| |
| void EasyUnlockServiceRegular::SetAutoPairingResult( |
| bool success, |
| const std::string& error) { |
| DCHECK(!auto_pairing_callback_.is_null()); |
| |
| auto_pairing_callback_.Run(success, error); |
| auto_pairing_callback_.Reset(); |
| } |
| |
| void EasyUnlockServiceRegular::InitializeInternal() { |
| proximity_auth::ScreenlockBridge::Get()->AddObserver(this); |
| registrar_.Init(profile()->GetPrefs()); |
| registrar_.Add( |
| prefs::kEasyUnlockAllowed, |
| base::Bind(&EasyUnlockServiceRegular::OnPrefsChanged, |
| base::Unretained(this))); |
| registrar_.Add(prefs::kEasyUnlockProximityRequired, |
| base::Bind(&EasyUnlockServiceRegular::OnPrefsChanged, |
| base::Unretained(this))); |
| |
| OnPrefsChanged(); |
| |
| #if defined(OS_CHROMEOS) |
| if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| proximity_auth::switches::kEnableBluetoothLowEnergyDiscovery)) { |
| pref_manager_.reset( |
| new proximity_auth::ProximityAuthPrefManager(profile()->GetPrefs())); |
| GetCryptAuthDeviceManager()->AddObserver(this); |
| LoadRemoteDevices(); |
| } |
| #endif |
| } |
| |
| void EasyUnlockServiceRegular::ShutdownInternal() { |
| #if defined(OS_CHROMEOS) |
| short_lived_user_context_.reset(); |
| #endif |
| |
| turn_off_flow_status_ = EasyUnlockService::IDLE; |
| registrar_.RemoveAll(); |
| proximity_auth::ScreenlockBridge::Get()->RemoveObserver(this); |
| } |
| |
| bool EasyUnlockServiceRegular::IsAllowedInternal() const { |
| #if defined(OS_CHROMEOS) |
| user_manager::UserManager* user_manager = user_manager::UserManager::Get(); |
| if (!user_manager->IsLoggedInAsUserWithGaiaAccount()) |
| return false; |
| |
| // TODO(tengs): Ephemeral accounts generate a new enrollment every time they |
| // are added, so disable Smart Lock to reduce enrollments on server. However, |
| // ephemeral accounts can be locked, so we should revisit this use case. |
| if (user_manager->IsCurrentUserNonCryptohomeDataEphemeral()) |
| return false; |
| |
| if (!chromeos::ProfileHelper::IsPrimaryProfile(profile())) |
| return false; |
| |
| if (!profile()->GetPrefs()->GetBoolean(prefs::kEasyUnlockAllowed)) |
| return false; |
| |
| return true; |
| #else |
| // TODO(xiyuan): Revisit when non-chromeos platforms are supported. |
| return false; |
| #endif |
| } |
| |
| void EasyUnlockServiceRegular::OnWillFinalizeUnlock(bool success) { |
| will_unlock_using_easy_unlock_ = success; |
| } |
| |
| void EasyUnlockServiceRegular::OnSuspendDoneInternal() { |
| lock_screen_last_shown_timestamp_ = base::TimeTicks::Now(); |
| } |
| |
| void EasyUnlockServiceRegular::OnSyncFinished( |
| cryptauth::CryptAuthDeviceManager::SyncResult sync_result, |
| cryptauth::CryptAuthDeviceManager::DeviceChangeResult |
| device_change_result) { |
| if (device_change_result != |
| cryptauth::CryptAuthDeviceManager::DeviceChangeResult::CHANGED) |
| return; |
| |
| if (proximity_auth::ScreenlockBridge::Get()->IsLocked()) { |
| PA_LOG(INFO) << "Deferring device load until screen is unlocked."; |
| deferring_device_load_ = true; |
| } else { |
| LoadRemoteDevices(); |
| } |
| } |
| |
| void EasyUnlockServiceRegular::OnScreenDidLock( |
| proximity_auth::ScreenlockBridge::LockHandler::ScreenType screen_type) { |
| will_unlock_using_easy_unlock_ = false; |
| lock_screen_last_shown_timestamp_ = base::TimeTicks::Now(); |
| } |
| |
| void EasyUnlockServiceRegular::OnScreenDidUnlock( |
| proximity_auth::ScreenlockBridge::LockHandler::ScreenType screen_type) { |
| // Notifications of signin screen unlock events can also reach this code path; |
| // disregard them. |
| if (screen_type != proximity_auth::ScreenlockBridge::LockHandler::LOCK_SCREEN) |
| return; |
| |
| // Only record metrics for users who have enabled the feature. |
| if (IsEnabled()) { |
| EasyUnlockAuthEvent event = |
| will_unlock_using_easy_unlock_ |
| ? EASY_UNLOCK_SUCCESS |
| : GetPasswordAuthEvent(); |
| RecordEasyUnlockScreenUnlockEvent(event); |
| |
| if (will_unlock_using_easy_unlock_) { |
| RecordEasyUnlockScreenUnlockDuration( |
| base::TimeTicks::Now() - lock_screen_last_shown_timestamp_); |
| } |
| } |
| |
| will_unlock_using_easy_unlock_ = false; |
| |
| // If we synced remote devices while the screen was locked, we can now load |
| // the new remote devices. |
| if (deferring_device_load_) { |
| PA_LOG(INFO) << "Loading deferred devices after screen unlock."; |
| deferring_device_load_ = false; |
| LoadRemoteDevices(); |
| } |
| } |
| |
| void EasyUnlockServiceRegular::OnFocusedUserChanged( |
| const AccountId& account_id) { |
| // Nothing to do. |
| } |
| |
| void EasyUnlockServiceRegular::OnPrefsChanged() { |
| SyncProfilePrefsToLocalState(); |
| UpdateAppState(); |
| } |
| |
| void EasyUnlockServiceRegular::SetTurnOffFlowStatus(TurnOffFlowStatus status) { |
| turn_off_flow_status_ = status; |
| NotifyTurnOffOperationStatusChanged(); |
| } |
| |
| void EasyUnlockServiceRegular::OnToggleEasyUnlockApiComplete( |
| const cryptauth::ToggleEasyUnlockResponse& response) { |
| cryptauth_client_.reset(); |
| |
| SetRemoteDevices(base::ListValue()); |
| SetTurnOffFlowStatus(IDLE); |
| ReloadAppAndLockScreen(); |
| } |
| |
| void EasyUnlockServiceRegular::OnToggleEasyUnlockApiFailed( |
| const std::string& error_message) { |
| LOG(WARNING) << "Failed to turn off Smart Lock: " << error_message; |
| SetTurnOffFlowStatus(FAIL); |
| } |
| |
| void EasyUnlockServiceRegular::SyncProfilePrefsToLocalState() { |
| PrefService* local_state = |
| g_browser_process ? g_browser_process->local_state() : NULL; |
| PrefService* profile_prefs = profile()->GetPrefs(); |
| if (!local_state || !profile_prefs) |
| return; |
| |
| // Create the dictionary of Easy Unlock preferences for the current user. The |
| // items in the dictionary are the same profile prefs used for Easy Unlock. |
| std::unique_ptr<base::DictionaryValue> user_prefs_dict( |
| new base::DictionaryValue()); |
| user_prefs_dict->SetBooleanWithoutPathExpansion( |
| prefs::kEasyUnlockProximityRequired, |
| profile_prefs->GetBoolean(prefs::kEasyUnlockProximityRequired)); |
| |
| DictionaryPrefUpdate update(local_state, |
| prefs::kEasyUnlockLocalStateUserPrefs); |
| update->SetWithoutPathExpansion(GetAccountId().GetUserEmail(), |
| std::move(user_prefs_dict)); |
| } |
| |
| cryptauth::CryptAuthEnrollmentManager* |
| EasyUnlockServiceRegular::GetCryptAuthEnrollmentManager() { |
| cryptauth::CryptAuthEnrollmentManager* manager = |
| ChromeCryptAuthServiceFactory::GetInstance() |
| ->GetForBrowserContext(profile()) |
| ->GetCryptAuthEnrollmentManager(); |
| DCHECK(manager); |
| return manager; |
| } |
| |
| cryptauth::CryptAuthDeviceManager* |
| EasyUnlockServiceRegular::GetCryptAuthDeviceManager() { |
| cryptauth::CryptAuthDeviceManager* manager = |
| ChromeCryptAuthServiceFactory::GetInstance() |
| ->GetForBrowserContext(profile()) |
| ->GetCryptAuthDeviceManager(); |
| DCHECK(manager); |
| return manager; |
| } |