15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/signin/easy_unlock_service.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h"
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/command_line.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/logging.h"
101675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch#include "base/metrics/field_trial.h"
1134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/prefs/pref_service.h"
1334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
145b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#include "base/thread_task_runner_handle.h"
155b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#include "base/time/time.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/values.h"
1734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "chrome/browser/browser_process.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/component_loader.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/signin/easy_unlock_auth_attempt.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/signin/easy_unlock_service_factory.h"
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/signin/easy_unlock_service_observer.h"
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/signin/screenlock_bridge.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/common/extensions/api/easy_unlock_private.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/common/extensions/extension_constants.h"
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/pref_names.h"
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h"
3034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "components/user_manager/user.h"
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter.h"
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_factory.h"
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/event_router.h"
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extension_registry.h"
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_system.h"
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/one_shot_event.h"
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "grit/browser_resources.h"
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS)
4034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
4134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "chrome/browser/chromeos/login/session/user_session_manager.h"
4234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
431675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch#include "chromeos/chromeos_switches.h"
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/dbus/dbus_thread_manager.h"
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/dbus/power_manager_client.h"
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extensions::ComponentLoader* GetComponentLoader(
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::BrowserContext* context) {
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  extensions::ExtensionSystem* extension_system =
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::ExtensionSystem::Get(context);
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* extension_service = extension_system->extension_service();
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return extension_service->component_loader();
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)PrefService* GetLocalState() {
5934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  return g_browser_process ? g_browser_process->local_state() : NULL;
6034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
6134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)EasyUnlockService* EasyUnlockService::Get(Profile* profile) {
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return EasyUnlockServiceFactory::GetForProfile(profile);
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// static
7034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EasyUnlockService* EasyUnlockService::GetForUser(
7134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    const user_manager::User& user) {
7234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#if defined(OS_CHROMEOS)
7334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(&user);
7434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (!profile)
7534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return NULL;
7634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  return EasyUnlockService::Get(profile);
7734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#else
7834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  return NULL;
7934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#endif
8034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
8134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
821675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch// static
831675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochbool EasyUnlockService::IsSignInEnabled() {
841675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch#if defined(OS_CHROMEOS)
851675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  const std::string group_name =
861675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      base::FieldTrialList::FindFullName("EasySignIn");
871675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
881675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (CommandLine::ForCurrentProcess()->HasSwitch(
891675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch          chromeos::switches::kDisableEasySignin)) {
901675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    return false;
911675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
921675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
931675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  return group_name == "Enable";
941675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch#else
951675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  return false;
961675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch#endif
971675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch}
981675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class EasyUnlockService::BluetoothDetector
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : public device::BluetoothAdapter::Observer {
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public:
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  explicit BluetoothDetector(EasyUnlockService* service)
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      : service_(service),
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        weak_ptr_factory_(this) {
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual ~BluetoothDetector() {
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (adapter_.get())
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      adapter_->RemoveObserver(this);
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void Initialize() {
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return;
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    device::BluetoothAdapterFactory::GetAdapter(
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(&BluetoothDetector::OnAdapterInitialized,
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool IsPresent() const { return adapter_.get() && adapter_->IsPresent(); }
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // device::BluetoothAdapter::Observer:
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                     bool present) OVERRIDE {
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    service_->OnBluetoothAdapterPresentChanged();
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter) {
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    adapter_ = adapter;
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    adapter_->AddObserver(this);
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    service_->OnBluetoothAdapterPresentChanged();
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Owner of this class and should out-live this class.
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EasyUnlockService* service_;
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<device::BluetoothAdapter> adapter_;
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::WeakPtrFactory<BluetoothDetector> weak_ptr_factory_;
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BluetoothDetector);
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS)
14534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)class EasyUnlockService::PowerMonitor
14634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    : public chromeos::PowerManagerClient::Observer {
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
1485b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  explicit PowerMonitor(EasyUnlockService* service)
1495b892326406927b709cdaf6c384d4ababf456332Ben Murdoch      : service_(service),
1505b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        waking_up_(false),
1515b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        weak_ptr_factory_(this) {
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        AddObserver(this);
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~PowerMonitor() {
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        RemoveObserver(this);
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1615b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  bool waking_up() const { return waking_up_; }
1625b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // chromeos::PowerManagerClient::Observer:
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SuspendImminent() OVERRIDE {
1665b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    service_->PrepareForSuspend();
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SuspendDone(const base::TimeDelta& sleep_duration) OVERRIDE {
1705b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    waking_up_ = true;
1715b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1725b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        FROM_HERE,
1735b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        base::Bind(&PowerMonitor::ResetWakingUp,
1745b892326406927b709cdaf6c384d4ababf456332Ben Murdoch                   weak_ptr_factory_.GetWeakPtr()),
1755b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        base::TimeDelta::FromSeconds(5));
1765b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    service_->UpdateAppState();
1775b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    // Note that |this| may get deleted after |UpdateAppState| is called.
1785b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  }
1795b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
1805b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  void ResetWakingUp() {
1815b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    waking_up_ = false;
1825b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    service_->UpdateAppState();
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EasyUnlockService* service_;
1865b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  bool waking_up_;
1875b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  base::WeakPtrFactory<PowerMonitor> weak_ptr_factory_;
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)EasyUnlockService::EasyUnlockService(Profile* profile)
1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : profile_(profile),
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      bluetooth_detector_(new BluetoothDetector(this)),
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      shut_down_(false),
1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      weak_ptr_factory_(this) {
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  extensions::ExtensionSystem::Get(profile_)->ready().Post(
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&EasyUnlockService::Initialize,
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)EasyUnlockService::~EasyUnlockService() {
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EasyUnlockService::RegisterProfilePrefs(
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterBooleanPref(
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      prefs::kEasyUnlockEnabled,
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      false,
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterDictionaryPref(
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      prefs::kEasyUnlockPairing,
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new base::DictionaryValue(),
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterBooleanPref(
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      prefs::kEasyUnlockAllowed,
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      true,
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
22434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// static
22534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)void EasyUnlockService::RegisterPrefs(PrefRegistrySimple* registry) {
22634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  registry->RegisterDictionaryPref(prefs::kEasyUnlockHardlockState);
22734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
22834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
22934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// static
2305b892326406927b709cdaf6c384d4ababf456332Ben Murdochvoid EasyUnlockService::ResetLocalStateForUser(const std::string& user_id) {
23134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  DCHECK(!user_id.empty());
23234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
23334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  PrefService* local_state = GetLocalState();
23434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (!local_state)
23534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
23634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
23734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  DictionaryPrefUpdate update(local_state, prefs::kEasyUnlockHardlockState);
23834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  update->RemoveWithoutPathExpansion(user_id, NULL);
23934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
24034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool EasyUnlockService::IsAllowed() {
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (shut_down_)
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IsAllowedInternal())
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS)
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!bluetooth_detector_->IsPresent())
25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(xiyuan): Revisit when non-chromeos platforms are supported.
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
25934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)void EasyUnlockService::SetHardlockState(
26034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    EasyUnlockScreenlockStateHandler::HardlockState state) {
26134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  const std::string user_id = GetUserEmail();
26234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (user_id.empty())
26334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
26434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
26534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  SetHardlockStateForUser(user_id, state);
26634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
26734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
26834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EasyUnlockScreenlockStateHandler::HardlockState
26934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EasyUnlockService::GetHardlockState() const {
270e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  EasyUnlockScreenlockStateHandler::HardlockState state;
271e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  if (GetPersistedHardlockState(&state))
272e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    return state;
273e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
274e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  return EasyUnlockScreenlockStateHandler::NO_HARDLOCK;
275e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch}
276e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
277e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdochbool EasyUnlockService::GetPersistedHardlockState(
278e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    EasyUnlockScreenlockStateHandler::HardlockState* state) const {
27934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  std::string user_id = GetUserEmail();
28034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (user_id.empty())
281e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    return false;
28234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
28334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  PrefService* local_state = GetLocalState();
28434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (!local_state)
285e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    return false;
28634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
28734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  const base::DictionaryValue* dict =
28834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      local_state->GetDictionary(prefs::kEasyUnlockHardlockState);
289e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  int state_int;
290e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  if (dict && dict->GetIntegerWithoutPathExpansion(user_id, &state_int)) {
291e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    *state =
292e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch        static_cast<EasyUnlockScreenlockStateHandler::HardlockState>(state_int);
293e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    return true;
294e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  }
29534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
296e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  return false;
29734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
29834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
299e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdochvoid EasyUnlockService::ShowInitialUserState() {
30078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  if (!GetScreenlockStateHandler())
30178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return;
30278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
303e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  EasyUnlockScreenlockStateHandler::HardlockState state;
304e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  bool has_persisted_state = GetPersistedHardlockState(&state);
305e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  if (!has_persisted_state)
30634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
307e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
308e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  if (state == EasyUnlockScreenlockStateHandler::NO_HARDLOCK) {
309e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    // Show connecting icon early when there is a persisted non hardlock state.
310e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    UpdateScreenlockState(
311e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch        EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
312e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  } else {
31334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    screenlock_state_handler_->MaybeShowHardlockUI();
314e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  }
31534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
31634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
3176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)EasyUnlockScreenlockStateHandler*
3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EasyUnlockService::GetScreenlockStateHandler() {
3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!IsAllowed())
3206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return NULL;
3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!screenlock_state_handler_) {
3226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    screenlock_state_handler_.reset(new EasyUnlockScreenlockStateHandler(
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GetUserEmail(),
32434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)        GetHardlockState(),
3256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        ScreenlockBridge::Get()));
3266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return screenlock_state_handler_.get();
3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool EasyUnlockService::UpdateScreenlockState(
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EasyUnlockScreenlockStateHandler::State state) {
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EasyUnlockScreenlockStateHandler* handler = GetScreenlockStateHandler();
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!handler)
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
3356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  handler->ChangeState(state);
3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (state != EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED)
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    auth_attempt_.reset();
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::AttemptAuth(const std::string& user_id) {
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  auth_attempt_.reset(new EasyUnlockAuthAttempt(
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      profile_,
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetUserEmail(),
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetType() == TYPE_REGULAR ? EasyUnlockAuthAttempt::TYPE_UNLOCK
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                : EasyUnlockAuthAttempt::TYPE_SIGNIN));
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!auth_attempt_->Start(user_id))
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    auth_attempt_.reset();
3516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::FinalizeUnlock(bool success) {
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (auth_attempt_)
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    auth_attempt_->FinalizeUnlock(GetUserEmail(), success);
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  auth_attempt_.reset();
3576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::FinalizeSignin(const std::string& key) {
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!auth_attempt_)
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string wrapped_secret = GetWrappedSecret();
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!wrapped_secret.empty())
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    auth_attempt_->FinalizeSignin(GetUserEmail(), wrapped_secret, key);
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  auth_attempt_.reset();
3666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
36834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)void EasyUnlockService::CheckCryptohomeKeysAndMaybeHardlock() {
36934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#if defined(OS_CHROMEOS)
37034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  std::string user_id = GetUserEmail();
37134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (user_id.empty())
37234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
37334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
37434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  const base::ListValue* device_list = GetRemoteDevices();
37534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  std::set<std::string> paired_devices;
37634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (device_list) {
37734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    chromeos::EasyUnlockDeviceKeyDataList parsed_paired;
37834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    chromeos::EasyUnlockKeyManager::RemoteDeviceListToDeviceDataList(
37934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)        *device_list, &parsed_paired);
38034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    for (const auto& device_key_data : parsed_paired)
38129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch      paired_devices.insert(device_key_data.psk);
38234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  }
38334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (paired_devices.empty()) {
38434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    SetHardlockState(EasyUnlockScreenlockStateHandler::NO_PAIRING);
38534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
38634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  }
38734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
38834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  // No need to compare if a change is already recorded.
389e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  if (GetHardlockState() == EasyUnlockScreenlockStateHandler::PAIRING_CHANGED ||
390e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch      GetHardlockState() == EasyUnlockScreenlockStateHandler::PAIRING_ADDED) {
39134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
392e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  }
39334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
39434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  chromeos::EasyUnlockKeyManager* key_manager =
39534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager();
39634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  DCHECK(key_manager);
39734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
39834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  key_manager->GetDeviceDataList(
39934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      chromeos::UserContext(user_id),
40034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      base::Bind(&EasyUnlockService::OnCryptohomeKeysFetchedForChecking,
40134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
40234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)                 user_id,
40334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)                 paired_devices));
40434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#endif
40534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
40634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
4075b892326406927b709cdaf6c384d4ababf456332Ben Murdochvoid EasyUnlockService::SetTrialRun() {
4085b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  DCHECK(GetType() == TYPE_REGULAR);
4095b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
4105b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  EasyUnlockScreenlockStateHandler* handler = GetScreenlockStateHandler();
4115b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  if (handler)
4125b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    handler->SetTrialRun();
4135b892326406927b709cdaf6c384d4ababf456332Ben Murdoch}
4145b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
4156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void EasyUnlockService::AddObserver(EasyUnlockServiceObserver* observer) {
4166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  observers_.AddObserver(observer);
4176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
4186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void EasyUnlockService::RemoveObserver(EasyUnlockServiceObserver* observer) {
4206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  observers_.RemoveObserver(observer);
4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid  EasyUnlockService::Shutdown() {
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (shut_down_)
4256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shut_down_ = true;
4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ShutdownInternal();
4296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  weak_ptr_factory_.InvalidateWeakPtrs();
43103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResetScreenlockState();
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bluetooth_detector_.reset();
43403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_CHROMEOS)
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  power_monitor_.reset();
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EasyUnlockService::LoadApp() {
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(IsAllowed());
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::FilePath easy_unlock_path;
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS)
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  easy_unlock_path = base::FilePath("/usr/share/chromeos-assets/easy_unlock");
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif  // defined(OS_CHROMEOS)
4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef NDEBUG
4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Only allow app path override switch for debug build.
4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (command_line->HasSwitch(switches::kEasyUnlockAppPath)) {
4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    easy_unlock_path =
4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        command_line->GetSwitchValuePath(switches::kEasyUnlockAppPath);
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif  // !defined(NDEBUG)
4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!easy_unlock_path.empty()) {
45803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    extensions::ComponentLoader* loader = GetComponentLoader(profile_);
45903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!loader->Exists(extension_misc::kEasyUnlockAppId))
46003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      loader->Add(IDR_EASY_UNLOCK_MANIFEST, easy_unlock_path);
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExtensionService* extension_service =
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        extensions::ExtensionSystem::Get(profile_)->extension_service();
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    extension_service->EnableExtension(extension_misc::kEasyUnlockAppId);
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    NotifyUserUpdated();
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif  // defined(GOOGLE_CHROME_BUILD)
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::DisableAppIfLoaded() {
47203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  extensions::ComponentLoader* loader = GetComponentLoader(profile_);
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!loader->Exists(extension_misc::kEasyUnlockAppId))
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExtensionService* extension_service =
4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extensions::ExtensionSystem::Get(profile_)->extension_service();
4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extension_service->DisableExtension(extension_misc::kEasyUnlockAppId,
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      extensions::Extension::DISABLE_RELOAD);
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::UnloadApp() {
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetComponentLoader(profile_)->Remove(extension_misc::kEasyUnlockAppId);
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::ReloadApp() {
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Make sure lock screen state set by the extension gets reset.
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResetScreenlockState();
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!GetComponentLoader(profile_)->Exists(extension_misc::kEasyUnlockAppId))
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extensions::ExtensionSystem* extension_system =
4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extensions::ExtensionSystem::Get(profile_);
4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extension_system->extension_service()->ReloadExtension(
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extension_misc::kEasyUnlockAppId);
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NotifyUserUpdated();
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
49903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void EasyUnlockService::UpdateAppState() {
5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (IsAllowed()) {
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LoadApp();
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS)
5045b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    if (!power_monitor_)
5055b892326406927b709cdaf6c384d4ababf456332Ben Murdoch      power_monitor_.reset(new PowerMonitor(this));
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
5076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else {
5085b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    bool bluetooth_waking_up = false;
5095b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#if defined(OS_CHROMEOS)
5105b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    // If the service is not allowed due to bluetooth not being detected just
5115b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    // after system suspend is done, give bluetooth more time to be detected
5125b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    // before disabling the app (and resetting screenlock state).
5135b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    bluetooth_waking_up =
5145b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        power_monitor_.get() && power_monitor_->waking_up() &&
5155b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        !bluetooth_detector_->IsPresent();
5165b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#endif
5175b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
5185b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    if (!bluetooth_waking_up) {
5195b892326406927b709cdaf6c384d4ababf456332Ben Murdoch      DisableAppIfLoaded();
5205b892326406927b709cdaf6c384d4ababf456332Ben Murdoch      ResetScreenlockState();
5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS)
5225b892326406927b709cdaf6c384d4ababf456332Ben Murdoch      power_monitor_.reset();
5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
5245b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    }
5256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
5266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
5276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::NotifyUserUpdated() {
5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string user_id = GetUserEmail();
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (user_id.empty())
5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
53203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Notify the easy unlock app that the user info changed.
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extensions::api::easy_unlock_private::UserInfo info;
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info.user_id = user_id;
5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info.logged_in = GetType() == TYPE_REGULAR;
5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info.data_ready = info.logged_in || GetRemoteDevices() != NULL;
5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::ListValue> args(new base::ListValue());
5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  args->Append(info.ToValue().release());
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<extensions::Event> event(new extensions::Event(
5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extensions::api::easy_unlock_private::OnUserInfoUpdated::kEventName,
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      args.Pass()));
5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extensions::EventRouter::Get(profile_)->DispatchEventToExtension(
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       extension_misc::kEasyUnlockAppId, event.Pass());
54803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
54903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::NotifyTurnOffOperationStatusChanged() {
5516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  FOR_EACH_OBSERVER(
5526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      EasyUnlockServiceObserver, observers_, OnTurnOffOperationStatusChanged());
5536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
5546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::ResetScreenlockState() {
5561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  screenlock_state_handler_.reset();
5571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  auth_attempt_.reset();
5581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)void EasyUnlockService::SetScreenlockHardlockedState(
56134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    EasyUnlockScreenlockStateHandler::HardlockState state) {
56234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (screenlock_state_handler_)
56334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    screenlock_state_handler_->SetHardlockState(state);
56434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (state != EasyUnlockScreenlockStateHandler::NO_HARDLOCK)
56534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    auth_attempt_.reset();
56634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
56734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::Initialize() {
5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  InitializeInternal();
5706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS)
5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Only start Bluetooth detection for ChromeOS since the feature is
5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // only offered on ChromeOS. Enabling this on non-ChromeOS platforms
5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // previously introduced a performance regression: http://crbug.com/404482
5751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Make sure not to reintroduce a performance regression if re-enabling on
5761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // additional platforms.
5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(xiyuan): Revisit when non-chromeos platforms are supported.
5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bluetooth_detector_->Initialize();
5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // defined(OS_CHROMEOS)
5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
58103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockService::OnBluetoothAdapterPresentChanged() {
5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UpdateAppState();
5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
58634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)void EasyUnlockService::SetHardlockStateForUser(
58734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      const std::string& user_id,
58834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      EasyUnlockScreenlockStateHandler::HardlockState state) {
58934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  DCHECK(!user_id.empty());
59034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
59134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  PrefService* local_state = GetLocalState();
59234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (!local_state)
59334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
59434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
59534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  DictionaryPrefUpdate update(local_state, prefs::kEasyUnlockHardlockState);
59634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  update->SetIntegerWithoutPathExpansion(user_id, static_cast<int>(state));
59734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
59834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (GetUserEmail() == user_id)
59934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    SetScreenlockHardlockedState(state);
60034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
60134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
60234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#if defined(OS_CHROMEOS)
60334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)void EasyUnlockService::OnCryptohomeKeysFetchedForChecking(
60434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    const std::string& user_id,
60534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    const std::set<std::string> paired_devices,
60634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    bool success,
60734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    const chromeos::EasyUnlockDeviceKeyDataList& key_data_list) {
60834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  DCHECK(!user_id.empty() && !paired_devices.empty());
60934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
61034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (!success) {
61134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    SetHardlockStateForUser(user_id,
61234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)                            EasyUnlockScreenlockStateHandler::NO_PAIRING);
61334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
61434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  }
61534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
61634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  std::set<std::string> devices_in_cryptohome;
61734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  for (const auto& device_key_data : key_data_list)
61829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    devices_in_cryptohome.insert(device_key_data.psk);
61934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
6205b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  if (paired_devices != devices_in_cryptohome ||
6215b892326406927b709cdaf6c384d4ababf456332Ben Murdoch      GetHardlockState() == EasyUnlockScreenlockStateHandler::NO_PAIRING) {
622e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    SetHardlockStateForUser(
623e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch        user_id,
624e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch        devices_in_cryptohome.empty()
625e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch            ? EasyUnlockScreenlockStateHandler::PAIRING_ADDED
626e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch            : EasyUnlockScreenlockStateHandler::PAIRING_CHANGED);
62734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  }
62834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
62934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#endif
63034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
6315b892326406927b709cdaf6c384d4ababf456332Ben Murdochvoid EasyUnlockService::PrepareForSuspend() {
6325b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  DisableAppIfLoaded();
6335b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  if (screenlock_state_handler_ && screenlock_state_handler_->IsActive()) {
6345b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    UpdateScreenlockState(
6355b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
6365b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  }
6375b892326406927b709cdaf6c384d4ababf456332Ben Murdoch}
6385b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
639