Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(592)

Unified Diff: chrome/browser/signin/easy_unlock_service_signin_chromeos.cc

Issue 583403002: [Easy signin] Update the logic for getting user device list from cryptohome (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/signin/easy_unlock_service_signin_chromeos.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
diff --git a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
index 5004a1697071210bc5cff695b5e942655174acab..f4f45811a6c3dd51a98244387f4cf4ff1aaf9e2f 100644
--- a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
+++ b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
@@ -4,29 +4,100 @@
#include "chrome/browser/signin/easy_unlock_service_signin_chromeos.h"
+#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/location.h"
#include "base/logging.h"
-#include "base/values.h"
+#include "base/stl_util.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
#include "chrome/browser/chromeos/login/session/user_session_manager.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/login/auth/user_context.h"
+namespace {
+
+// The maximum allowed backoff interval when waiting for cryptohome to start.
+uint32 kMaxCryptohomeBackoffIntervalMs = 10000u;
+
+// If the data load fails, the initial interval after which the load will be
+// retried. Further intervals will exponentially increas by factor 2.
+uint32 kInitialCryptohomeBackoffIntervalMs = 200u;
+
+// Calculates the backoff interval that should be used next.
+// |backoff| The last backoff interval used.
+uint32 GetNextBackoffInterval(uint32 backoff) {
+ if (backoff == 0u)
+ return kInitialCryptohomeBackoffIntervalMs;
+ return backoff * 2;
+}
+
+void LoadDataForUser(
+ const std::string& user_id,
+ uint32 backoff_ms,
+ const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback);
+
+// Callback passed to |LoadDataForUser()|.
+// If |LoadDataForUser| function succeeded, it invokes |callback| with the
+// results.
+// If |LoadDataForUser| failed and further retries are allowed, schedules new
+// |LoadDataForUser| call with some backoff. If no further retires are allowed,
+// it invokes |callback| with the |LoadDataForUser| results.
+void RetryDataLoadOnError(
+ const std::string& user_id,
+ uint32 backoff_ms,
+ const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback,
+ bool success,
+ const chromeos::EasyUnlockDeviceKeyDataList& data_list) {
+ if (success) {
+ callback.Run(success, data_list);
+ return;
+ }
+
+ uint32 next_backoff_ms = GetNextBackoffInterval(backoff_ms);
+ if (next_backoff_ms > kMaxCryptohomeBackoffIntervalMs) {
+ callback.Run(false, data_list);
+ return;
+ }
+
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&LoadDataForUser, user_id, next_backoff_ms, callback),
+ base::TimeDelta::FromMilliseconds(next_backoff_ms));
+}
+
+// Loads device data list associated with the user's Easy unlock keys.
+void LoadDataForUser(
+ const std::string& user_id,
+ uint32 backoff_ms,
+ const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback) {
+ chromeos::EasyUnlockKeyManager* key_manager =
+ chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager();
+ DCHECK(key_manager);
+
+ key_manager->GetDeviceDataList(
+ chromeos::UserContext(user_id),
+ base::Bind(&RetryDataLoadOnError, user_id, backoff_ms, callback));
+}
+
+} // namespace
+
+EasyUnlockServiceSignin::UserData::UserData()
+ : state(EasyUnlockServiceSignin::USER_DATA_STATE_INITIAL) {
+}
+
+EasyUnlockServiceSignin::UserData::~UserData() {}
+
EasyUnlockServiceSignin::EasyUnlockServiceSignin(Profile* profile)
: EasyUnlockService(profile),
+ allow_cryptohome_backoff_(true),
weak_ptr_factory_(this) {
}
EasyUnlockServiceSignin::~EasyUnlockServiceSignin() {
-}
-
-void EasyUnlockServiceSignin::SetAssociatedUser(const std::string& user_id) {
- if (user_id_ == user_id)
- return;
-
- user_id_ = user_id;
- FetchCryptohomeKeys();
+ STLDeleteContainerPairSecondPointers(user_data_.begin(), user_data_.end());
}
EasyUnlockService::Type EasyUnlockServiceSignin::GetType() const {
@@ -42,7 +113,6 @@ void EasyUnlockServiceSignin::LaunchSetup() {
}
const base::DictionaryValue* EasyUnlockServiceSignin::GetPermitAccess() const {
- // TODO(tbarzic): Implement this (http://crbug.com/401634).
return NULL;
}
@@ -56,7 +126,10 @@ void EasyUnlockServiceSignin::ClearPermitAccess() {
}
const base::ListValue* EasyUnlockServiceSignin::GetRemoteDevices() const {
- return remote_devices_value_.get();
+ const UserData* data = FindLoadedDataForCurrentUser();
+ if (!data)
+ return NULL;
+ return &data->remote_devices_value;
}
void EasyUnlockServiceSignin::SetRemoteDevices(
@@ -82,52 +155,72 @@ EasyUnlockService::TurnOffFlowStatus
}
std::string EasyUnlockServiceSignin::GetChallenge() const {
+ const UserData* data = FindLoadedDataForCurrentUser();
// TODO(xiyuan): Use correct remote device instead of hard coded first one.
- size_t device_index = 0;
- return device_index < remote_devices_.size()
- ? remote_devices_[device_index].challenge
- : std::string();
+ uint32 device_index = 0;
+ if (!data || data->devices.size() <= device_index)
+ return std::string();
+ return data->devices[device_index].challenge;
}
void EasyUnlockServiceSignin::InitializeInternal() {
}
bool EasyUnlockServiceSignin::IsAllowedInternal() {
- return !user_id_.empty() && !remote_devices_.empty() &&
+ return !user_id_.empty() &&
+ FindLoadedDataForCurrentUser() &&
CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kEnableEasySignin);
}
-void EasyUnlockServiceSignin::FetchCryptohomeKeys() {
- remote_devices_.clear();
- remote_devices_value_.reset();
- if (user_id_.empty()) {
- UpdateAppState();
+void EasyUnlockServiceSignin::LoadCurrentUserDataIfNeeded() {
+ if (user_id_.empty() ||
+ !CommandLine::ForCurrentProcess()->HasSwitch(
+ chromeos::switches::kEnableEasySignin))
return;
- }
- chromeos::EasyUnlockKeyManager* key_manager =
- chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager();
- DCHECK(key_manager);
- key_manager->GetDeviceDataList(
- chromeos::UserContext(user_id_),
- base::Bind(&EasyUnlockServiceSignin::OnCryptohomeKeysFetched,
- weak_ptr_factory_.GetWeakPtr()));
+ std::map<std::string, UserData*>::iterator it = user_data_.find(user_id_);
+ if (it == user_data_.end())
+ user_data_.insert(std::make_pair(user_id_, new UserData()));
+
+ UserData* data = user_data_[user_id_];
+
+ if (data->state != USER_DATA_STATE_INITIAL)
+ return;
+ data->state = USER_DATA_STATE_LOADING;
+
+ LoadDataForUser(
+ user_id_,
+ allow_cryptohome_backoff_ ? 0u : kMaxCryptohomeBackoffIntervalMs,
+ base::Bind(&EasyUnlockServiceSignin::OnUserDataLoaded,
+ weak_ptr_factory_.GetWeakPtr(),
+ user_id_));
}
-void EasyUnlockServiceSignin::OnCryptohomeKeysFetched(
+void EasyUnlockServiceSignin::OnUserDataLoaded(
+ const std::string& user_id,
bool success,
const chromeos::EasyUnlockDeviceKeyDataList& devices) {
- if (!success) {
- LOG(WARNING) << "Easy unlock cryptohome keys not found for user "
- << user_id_;
- return;
+ allow_cryptohome_backoff_ = false;
+
+ UserData* data = user_data_[user_id_];
+ data->state = USER_DATA_STATE_LOADED;
+ if (success) {
+ data->devices = devices;
+ chromeos::EasyUnlockKeyManager::DeviceDataListToRemoteDeviceList(
+ user_id, devices, &data->remote_devices_value);
}
+}
- remote_devices_ = devices;
- remote_devices_value_.reset(new base::ListValue);
- chromeos::EasyUnlockKeyManager::DeviceDataListToRemoteDeviceList(
- user_id_, remote_devices_, remote_devices_value_.get());
-
- UpdateAppState();
+const EasyUnlockServiceSignin::UserData*
+ EasyUnlockServiceSignin::FindLoadedDataForCurrentUser() const {
+ if (user_id_.empty())
+ return NULL;
+ std::map<std::string, UserData*>::const_iterator it =
+ user_data_.find(user_id_);
+ if (it == user_data_.end())
+ return NULL;
+ if (it->second->state != USER_DATA_STATE_LOADED)
+ return NULL;
+ return it->second;
}
« no previous file with comments | « chrome/browser/signin/easy_unlock_service_signin_chromeos.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698