Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / signin / easy_unlock_service_regular.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/signin/easy_unlock_service_regular.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/signin/easy_unlock_toggle_flow.h"
15 #include "chrome/browser/signin/screenlock_bridge.h"
16 #include "chrome/browser/ui/extensions/application_launch.h"
17 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/common/pref_names.h"
19 #include "components/pref_registry/pref_registry_syncable.h"
20 #include "extensions/browser/extension_system.h"
21
22 #if defined(OS_CHROMEOS)
23 #include "chrome/browser/chromeos/profiles/profile_helper.h"
24 #include "components/user_manager/user_manager.h"
25 #endif
26
27 namespace {
28
29 // Key name of the local device permit record dictonary in kEasyUnlockPairing.
30 const char kKeyPermitAccess[] = "permitAccess";
31
32 // Key name of the remote device list in kEasyUnlockPairing.
33 const char kKeyDevices[] = "devices";
34
35 // Key name of the phone public key in a device dictionary.
36 const char kKeyPhoneId[] = "permitRecord.id";
37
38 }  // namespace
39
40 EasyUnlockServiceRegular::EasyUnlockServiceRegular(Profile* profile)
41     : EasyUnlockService(profile),
42       turn_off_flow_status_(EasyUnlockService::IDLE) {
43 }
44
45 EasyUnlockServiceRegular::~EasyUnlockServiceRegular() {
46 }
47
48 EasyUnlockService::Type EasyUnlockServiceRegular::GetType() const {
49   return EasyUnlockService::TYPE_REGULAR;
50 }
51
52 std::string EasyUnlockServiceRegular::GetUserEmail() const {
53   return ScreenlockBridge::GetAuthenticatedUserEmail(profile());
54 }
55
56 void EasyUnlockServiceRegular::LaunchSetup() {
57   ExtensionService* service =
58       extensions::ExtensionSystem::Get(profile())->extension_service();
59   const extensions::Extension* extension =
60       service->GetExtensionById(extension_misc::kEasyUnlockAppId, false);
61
62   OpenApplication(AppLaunchParams(
63       profile(), extension, extensions::LAUNCH_CONTAINER_WINDOW, NEW_WINDOW));
64 }
65
66 const base::DictionaryValue* EasyUnlockServiceRegular::GetPermitAccess() const {
67   const base::DictionaryValue* pairing_dict =
68       profile()->GetPrefs()->GetDictionary(prefs::kEasyUnlockPairing);
69   const base::DictionaryValue* permit_dict = NULL;
70   if (pairing_dict &&
71       pairing_dict->GetDictionary(kKeyPermitAccess, &permit_dict))
72     return permit_dict;
73
74   return NULL;
75 }
76
77 void EasyUnlockServiceRegular::SetPermitAccess(
78     const base::DictionaryValue& permit) {
79   DictionaryPrefUpdate pairing_update(profile()->GetPrefs(),
80                                       prefs::kEasyUnlockPairing);
81   pairing_update->SetWithoutPathExpansion(kKeyPermitAccess, permit.DeepCopy());
82 }
83
84 void EasyUnlockServiceRegular::ClearPermitAccess() {
85   DictionaryPrefUpdate pairing_update(profile()->GetPrefs(),
86                                       prefs::kEasyUnlockPairing);
87   pairing_update->RemoveWithoutPathExpansion(kKeyPermitAccess, NULL);
88 }
89
90 const base::ListValue* EasyUnlockServiceRegular::GetRemoteDevices() const {
91   const base::DictionaryValue* pairing_dict =
92       profile()->GetPrefs()->GetDictionary(prefs::kEasyUnlockPairing);
93   const base::ListValue* devices = NULL;
94   if (pairing_dict && pairing_dict->GetList(kKeyDevices, &devices))
95     return devices;
96
97   return NULL;
98 }
99
100 void EasyUnlockServiceRegular::SetRemoteDevices(
101     const base::ListValue& devices) {
102   DictionaryPrefUpdate pairing_update(profile()->GetPrefs(),
103                                       prefs::kEasyUnlockPairing);
104   pairing_update->SetWithoutPathExpansion(kKeyDevices, devices.DeepCopy());
105 }
106
107 void EasyUnlockServiceRegular::ClearRemoteDevices() {
108   DictionaryPrefUpdate pairing_update(profile()->GetPrefs(),
109                                       prefs::kEasyUnlockPairing);
110   pairing_update->RemoveWithoutPathExpansion(kKeyDevices, NULL);
111 }
112
113 void EasyUnlockServiceRegular::RunTurnOffFlow() {
114   if (turn_off_flow_status_ == PENDING)
115     return;
116
117   SetTurnOffFlowStatus(PENDING);
118
119   // Currently there should only be one registered phone.
120   // TODO(xiyuan): Revisit this when server supports toggle for all or
121   // there are multiple phones.
122   const base::DictionaryValue* pairing_dict =
123       profile()->GetPrefs()->GetDictionary(prefs::kEasyUnlockPairing);
124   const base::ListValue* devices_list = NULL;
125   const base::DictionaryValue* first_device = NULL;
126   std::string phone_public_key;
127   if (!pairing_dict || !pairing_dict->GetList(kKeyDevices, &devices_list) ||
128       !devices_list || !devices_list->GetDictionary(0, &first_device) ||
129       !first_device ||
130       !first_device->GetString(kKeyPhoneId, &phone_public_key)) {
131     LOG(WARNING) << "Bad easy unlock pairing data, wiping out local data";
132     OnTurnOffFlowFinished(true);
133     return;
134   }
135
136   turn_off_flow_.reset(new EasyUnlockToggleFlow(
137       profile(),
138       phone_public_key,
139       false,
140       base::Bind(&EasyUnlockServiceRegular::OnTurnOffFlowFinished,
141                  base::Unretained(this))));
142   turn_off_flow_->Start();
143 }
144
145 void EasyUnlockServiceRegular::ResetTurnOffFlow() {
146   turn_off_flow_.reset();
147   SetTurnOffFlowStatus(IDLE);
148 }
149
150 EasyUnlockService::TurnOffFlowStatus
151     EasyUnlockServiceRegular::GetTurnOffFlowStatus() const {
152   return turn_off_flow_status_;
153 }
154
155 std::string EasyUnlockServiceRegular::GetChallenge() const {
156   return std::string();
157 }
158
159 std::string EasyUnlockServiceRegular::GetWrappedSecret() const {
160   return std::string();
161 }
162
163 void EasyUnlockServiceRegular::InitializeInternal() {
164   registrar_.Init(profile()->GetPrefs());
165   registrar_.Add(
166       prefs::kEasyUnlockAllowed,
167       base::Bind(&EasyUnlockServiceRegular::OnPrefsChanged,
168                  base::Unretained(this)));
169   OnPrefsChanged();
170 }
171
172 void EasyUnlockServiceRegular::ShutdownInternal() {
173   turn_off_flow_.reset();
174   turn_off_flow_status_ = EasyUnlockService::IDLE;
175   registrar_.RemoveAll();
176 }
177
178 bool EasyUnlockServiceRegular::IsAllowedInternal() {
179 #if defined(OS_CHROMEOS)
180   if (!user_manager::UserManager::Get()->IsLoggedInAsRegularUser())
181     return false;
182
183   if (!chromeos::ProfileHelper::IsPrimaryProfile(profile()))
184     return false;
185
186   return true;
187 #else
188   // TODO(xiyuan): Revisit when non-chromeos platforms are supported.
189   return false;
190 #endif
191 }
192
193 void EasyUnlockServiceRegular::OnPrefsChanged() {
194   UpdateAppState();
195 }
196
197 void EasyUnlockServiceRegular::SetTurnOffFlowStatus(TurnOffFlowStatus status) {
198   turn_off_flow_status_ = status;
199   NotifyTurnOffOperationStatusChanged();
200 }
201
202 void EasyUnlockServiceRegular::OnTurnOffFlowFinished(bool success) {
203   turn_off_flow_.reset();
204
205   if (!success) {
206     SetTurnOffFlowStatus(FAIL);
207     return;
208   }
209
210   ClearRemoteDevices();
211   SetTurnOffFlowStatus(IDLE);
212   ReloadApp();
213 }