11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/signin/easy_unlock_service_signin_chromeos.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/basictypes.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/location.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/logging.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/stl_util.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/thread_task_runner_handle.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/time/time.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h" 15ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/chromeos/login/session/user_session_manager.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/login/auth/user_context.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The maximum allowed backoff interval when waiting for cryptohome to start. 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciuint32 kMaxCryptohomeBackoffIntervalMs = 10000u; 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If the data load fails, the initial interval after which the load will be 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// retried. Further intervals will exponentially increas by factor 2. 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciuint32 kInitialCryptohomeBackoffIntervalMs = 200u; 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Calculates the backoff interval that should be used next. 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// |backoff| The last backoff interval used. 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciuint32 GetNextBackoffInterval(uint32 backoff) { 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (backoff == 0u) 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return kInitialCryptohomeBackoffIntervalMs; 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return backoff * 2; 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid LoadDataForUser( 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& user_id, 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 backoff_ms, 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback); 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Callback passed to |LoadDataForUser()|. 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If |LoadDataForUser| function succeeded, it invokes |callback| with the 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// results. 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If |LoadDataForUser| failed and further retries are allowed, schedules new 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// |LoadDataForUser| call with some backoff. If no further retires are allowed, 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// it invokes |callback| with the |LoadDataForUser| results. 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RetryDataLoadOnError( 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& user_id, 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 backoff_ms, 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback, 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool success, 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const chromeos::EasyUnlockDeviceKeyDataList& data_list) { 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (success) { 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(success, data_list); 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 next_backoff_ms = GetNextBackoffInterval(backoff_ms); 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (next_backoff_ms > kMaxCryptohomeBackoffIntervalMs) { 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(false, data_list); 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&LoadDataForUser, user_id, next_backoff_ms, callback), 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta::FromMilliseconds(next_backoff_ms)); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Loads device data list associated with the user's Easy unlock keys. 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid LoadDataForUser( 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& user_id, 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 backoff_ms, 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback) { 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chromeos::EasyUnlockKeyManager* key_manager = 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager(); 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(key_manager); 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci key_manager->GetDeviceDataList( 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chromeos::UserContext(user_id), 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RetryDataLoadOnError, user_id, backoff_ms, callback)); 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockServiceSignin::UserData::UserData() 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : state(EasyUnlockServiceSignin::USER_DATA_STATE_INITIAL) { 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockServiceSignin::UserData::~UserData() {} 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockServiceSignin::EasyUnlockServiceSignin(Profile* profile) 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : EasyUnlockService(profile), 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci allow_cryptohome_backoff_(true), 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service_active_(false), 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_(this) { 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockServiceSignin::~EasyUnlockServiceSignin() { 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockService::Type EasyUnlockServiceSignin::GetType() const { 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return EasyUnlockService::TYPE_SIGNIN; 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string EasyUnlockServiceSignin::GetUserEmail() const { 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return user_id_; 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::LaunchSetup() { 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst base::DictionaryValue* EasyUnlockServiceSignin::GetPermitAccess() const { 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::SetPermitAccess( 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::DictionaryValue& permit) { 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::ClearPermitAccess() { 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst base::ListValue* EasyUnlockServiceSignin::GetRemoteDevices() const { 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const UserData* data = FindLoadedDataForCurrentUser(); 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!data) 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return &data->remote_devices_value; 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::SetRemoteDevices( 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::ListValue& devices) { 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::ClearRemoteDevices() { 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::RunTurnOffFlow() { 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::ResetTurnOffFlow() { 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockService::TurnOffFlowStatus 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EasyUnlockServiceSignin::GetTurnOffFlowStatus() const { 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return EasyUnlockService::IDLE; 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string EasyUnlockServiceSignin::GetChallenge() const { 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const UserData* data = FindLoadedDataForCurrentUser(); 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(xiyuan): Use correct remote device instead of hard coded first one. 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 device_index = 0; 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!data || data->devices.size() <= device_index) 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return std::string(); 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return data->devices[device_index].challenge; 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string EasyUnlockServiceSignin::GetWrappedSecret() const { 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const UserData* data = FindLoadedDataForCurrentUser(); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(xiyuan): Use correct remote device instead of hard coded first one. 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 device_index = 0; 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!data || data->devices.size() <= device_index) 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return std::string(); 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return data->devices[device_index].wrapped_secret; 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 174ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdochvoid EasyUnlockServiceSignin::RecordEasySignInOutcome( 175ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch const std::string& user_id, 176ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch bool success) const { 177ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch DCHECK_EQ(GetUserEmail(), user_id); 178ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 179ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch chromeos::RecordEasyUnlockLoginEvent(success 180ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch ? chromeos::EASY_SIGN_IN_SUCCESS 181ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch : chromeos::EASY_SIGN_IN_FAILURE); 182ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch VLOG(1) << "Easy sign-in " << (success ? "success" : "failure"); 183ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch} 184ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 185ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdochvoid EasyUnlockServiceSignin::RecordPasswordLoginEvent( 186ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch const std::string& user_id) const { 187ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch DCHECK_EQ(GetUserEmail(), user_id); 188ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 189ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch chromeos::EasyUnlockLoginEvent event = 190ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch chromeos::EASY_SIGN_IN_LOGIN_EVENT_COUNT; 191ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (!GetRemoteDevices() || 192ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch GetHardlockState() == EasyUnlockScreenlockStateHandler::NO_PAIRING) { 193ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_NO_PAIRING; 194ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } else if (GetHardlockState() == 195ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch EasyUnlockScreenlockStateHandler::PAIRING_CHANGED) { 196ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_PAIRING_CHANGED; 197ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } else if (GetHardlockState() == 198ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch EasyUnlockScreenlockStateHandler::USER_HARDLOCK) { 199ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_USER_HARDLOCK; 200ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } else if (!screenlock_state_handler()) { 201ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_SERVICE_NOT_ACTIVE; 202ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } else { 203ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch switch (screenlock_state_handler()->state()) { 204ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_INACTIVE: 205ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_SERVICE_NOT_ACTIVE; 206ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 207ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH: 208ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_NO_BLUETOOTH; 209ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 210ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING: 211ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_BLUETOOTH_CONNECTING; 212ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 213ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_NO_PHONE: 214ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_NO_PHONE; 215ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 216ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED: 217ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_PHONE_NOT_AUTHENTICATED; 218ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 219ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED: 220ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_PHONE_LOCKED; 221ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 222ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE: 223ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_PHONE_NOT_LOCKABLE; 224ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 225ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY: 226ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_PHONE_NOT_NEARBY; 227ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 228ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED: 229ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_PHONE_UNSUPPORTED; 230ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 231ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch case EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED: 232ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch event = chromeos::PASSWORD_SIGN_IN_WITH_AUTHENTICATED_PHONE; 233ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch break; 234ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 235ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 236ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 237ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch chromeos::RecordEasyUnlockLoginEvent(event); 238ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch VLOG(1) << "EasySignIn password login event, event=" << event; 239ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch} 240ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::InitializeInternal() { 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (chromeos::LoginState::Get()->IsUserLoggedIn()) 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service_active_ = true; 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chromeos::LoginState::Get()->AddObserver(this); 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScreenlockBridge* screenlock_bridge = ScreenlockBridge::Get(); 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci screenlock_bridge->AddObserver(this); 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!screenlock_bridge->focused_user_id().empty()) 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnFocusedUserChanged(screenlock_bridge->focused_user_id()); 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::ShutdownInternal() { 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!service_active_) 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service_active_ = false; 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.InvalidateWeakPtrs(); 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScreenlockBridge::Get()->RemoveObserver(this); 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chromeos::LoginState::Get()->RemoveObserver(this); 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci STLDeleteContainerPairSecondPointers(user_data_.begin(), user_data_.end()); 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_data_.clear(); 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool EasyUnlockServiceSignin::IsAllowedInternal() { 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return service_active_ && 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !user_id_.empty() && 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !chromeos::LoginState::Get()->IsUserLoggedIn(); 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::OnScreenDidLock() { 273e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch // Update initial UI is when the account picker on login screen is ready. 274e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch ShowInitialUserState(); 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::OnScreenDidUnlock() { 2785b892326406927b709cdaf6c384d4ababf456332Ben Murdoch Shutdown(); 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::OnFocusedUserChanged(const std::string& user_id) { 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (user_id_ == user_id) 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Setting or clearing the user_id may changed |IsAllowed| value, so in these 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // cases update the app state. Otherwise, it's enough to notify the app the 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // user data has been updated. 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool should_update_app_state = user_id_.empty() != user_id.empty(); 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_id_ = user_id; 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResetScreenlockState(); 292e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch ShowInitialUserState(); 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (should_update_app_state) { 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UpdateAppState(); 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyUserUpdated(); 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LoadCurrentUserDataIfNeeded(); 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::LoggedInStateChanged() { 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!chromeos::LoginState::Get()->IsUserLoggedIn()) 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UnloadApp(); 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::LoadCurrentUserDataIfNeeded() { 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (user_id_.empty() || !service_active_) 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::map<std::string, UserData*>::iterator it = user_data_.find(user_id_); 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (it == user_data_.end()) 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_data_.insert(std::make_pair(user_id_, new UserData())); 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UserData* data = user_data_[user_id_]; 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (data->state != USER_DATA_STATE_INITIAL) 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci data->state = USER_DATA_STATE_LOADING; 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LoadDataForUser( 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_id_, 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci allow_cryptohome_backoff_ ? 0u : kMaxCryptohomeBackoffIntervalMs, 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&EasyUnlockServiceSignin::OnUserDataLoaded, 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr(), 3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_id_)); 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockServiceSignin::OnUserDataLoaded( 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& user_id, 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool success, 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const chromeos::EasyUnlockDeviceKeyDataList& devices) { 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci allow_cryptohome_backoff_ = false; 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UserData* data = user_data_[user_id_]; 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci data->state = USER_DATA_STATE_LOADED; 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (success) { 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci data->devices = devices; 3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chromeos::EasyUnlockKeyManager::DeviceDataListToRemoteDeviceList( 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_id, devices, &data->remote_devices_value); 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the fetched data belongs to the currently focused user, notify the app 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // that it has to refresh it's user data. 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (user_id == user_id_) 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyUserUpdated(); 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst EasyUnlockServiceSignin::UserData* 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EasyUnlockServiceSignin::FindLoadedDataForCurrentUser() const { 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (user_id_.empty()) 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::map<std::string, UserData*>::const_iterator it = 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_data_.find(user_id_); 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (it == user_data_.end()) 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (it->second->state != USER_DATA_STATE_LOADED) 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return it->second; 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 364