OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/signin/easy_unlock_service.h" | 5 #include "chrome/browser/signin/easy_unlock_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
11 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
| 12 #include "base/prefs/scoped_user_pref_update.h" |
12 #include "base/values.h" | 13 #include "base/values.h" |
13 #include "chrome/browser/extensions/component_loader.h" | 14 #include "chrome/browser/extensions/component_loader.h" |
14 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
15 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/signin/easy_unlock_screenlock_state_handler.h" | 17 #include "chrome/browser/signin/easy_unlock_screenlock_state_handler.h" |
17 #include "chrome/browser/signin/easy_unlock_service_factory.h" | 18 #include "chrome/browser/signin/easy_unlock_service_factory.h" |
| 19 #include "chrome/browser/signin/easy_unlock_service_observer.h" |
| 20 #include "chrome/browser/signin/easy_unlock_toggle_flow.h" |
18 #include "chrome/browser/signin/screenlock_bridge.h" | 21 #include "chrome/browser/signin/screenlock_bridge.h" |
19 #include "chrome/browser/ui/extensions/application_launch.h" | 22 #include "chrome/browser/ui/extensions/application_launch.h" |
20 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
21 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
22 #include "components/pref_registry/pref_registry_syncable.h" | 25 #include "components/pref_registry/pref_registry_syncable.h" |
23 #include "extensions/browser/extension_system.h" | 26 #include "extensions/browser/extension_system.h" |
24 #include "extensions/common/one_shot_event.h" | 27 #include "extensions/common/one_shot_event.h" |
25 #include "grit/browser_resources.h" | 28 #include "grit/browser_resources.h" |
26 | 29 |
27 #if defined(OS_CHROMEOS) | 30 #if defined(OS_CHROMEOS) |
28 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 31 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
29 #include "components/user_manager/user_manager.h" | 32 #include "components/user_manager/user_manager.h" |
30 #endif | 33 #endif |
31 | 34 |
32 namespace { | 35 namespace { |
33 | 36 |
| 37 // Key name of the local device permit record dictonary in kEasyUnlockPairing. |
| 38 const char kKeyPermitAccess[] = "permitAccess"; |
| 39 |
| 40 // Key name of the remote device list in kEasyUnlockPairing. |
| 41 const char kKeyDevices[] = "devices"; |
| 42 |
| 43 // Key name of the phone public key in a device dictionary. |
| 44 const char kKeyPhoneId[] = "permitRecord.id"; |
| 45 |
34 extensions::ComponentLoader* GetComponentLoader( | 46 extensions::ComponentLoader* GetComponentLoader( |
35 content::BrowserContext* context) { | 47 content::BrowserContext* context) { |
36 extensions::ExtensionSystem* extension_system = | 48 extensions::ExtensionSystem* extension_system = |
37 extensions::ExtensionSystem::Get(context); | 49 extensions::ExtensionSystem::Get(context); |
38 ExtensionService* extension_service = extension_system->extension_service(); | 50 ExtensionService* extension_service = extension_system->extension_service(); |
39 return extension_service->component_loader(); | 51 return extension_service->component_loader(); |
40 } | 52 } |
41 | 53 |
42 } // namespace | 54 } // namespace |
43 | 55 |
44 // static | 56 // static |
45 EasyUnlockService* EasyUnlockService::Get(Profile* profile) { | 57 EasyUnlockService* EasyUnlockService::Get(Profile* profile) { |
46 return EasyUnlockServiceFactory::GetForProfile(profile); | 58 return EasyUnlockServiceFactory::GetForProfile(profile); |
47 } | 59 } |
48 | 60 |
49 EasyUnlockService::EasyUnlockService(Profile* profile) | 61 EasyUnlockService::EasyUnlockService(Profile* profile) |
50 : profile_(profile), | 62 : profile_(profile), |
| 63 turn_off_flow_status_(IDLE), |
51 weak_ptr_factory_(this) { | 64 weak_ptr_factory_(this) { |
52 extensions::ExtensionSystem::Get(profile_)->ready().Post( | 65 extensions::ExtensionSystem::Get(profile_)->ready().Post( |
53 FROM_HERE, | 66 FROM_HERE, |
54 base::Bind(&EasyUnlockService::Initialize, | 67 base::Bind(&EasyUnlockService::Initialize, |
55 weak_ptr_factory_.GetWeakPtr())); | 68 weak_ptr_factory_.GetWeakPtr())); |
56 } | 69 } |
57 | 70 |
58 EasyUnlockService::~EasyUnlockService() { | 71 EasyUnlockService::~EasyUnlockService() { |
59 } | 72 } |
60 | 73 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 return false; | 114 return false; |
102 | 115 |
103 // It is only disabled when the trial exists and is in "Disable" group. | 116 // It is only disabled when the trial exists and is in "Disable" group. |
104 return base::FieldTrialList::FindFullName("EasyUnlock") != "Disable"; | 117 return base::FieldTrialList::FindFullName("EasyUnlock") != "Disable"; |
105 #else | 118 #else |
106 // TODO(xiyuan): Revisit when non-chromeos platforms are supported. | 119 // TODO(xiyuan): Revisit when non-chromeos platforms are supported. |
107 return false; | 120 return false; |
108 #endif | 121 #endif |
109 } | 122 } |
110 | 123 |
111 | |
112 EasyUnlockScreenlockStateHandler* | 124 EasyUnlockScreenlockStateHandler* |
113 EasyUnlockService::GetScreenlockStateHandler() { | 125 EasyUnlockService::GetScreenlockStateHandler() { |
114 if (!IsAllowed()) | 126 if (!IsAllowed()) |
115 return NULL; | 127 return NULL; |
116 if (!screenlock_state_handler_) { | 128 if (!screenlock_state_handler_) { |
117 screenlock_state_handler_.reset(new EasyUnlockScreenlockStateHandler( | 129 screenlock_state_handler_.reset(new EasyUnlockScreenlockStateHandler( |
118 ScreenlockBridge::GetAuthenticatedUserEmail(profile_), | 130 ScreenlockBridge::GetAuthenticatedUserEmail(profile_), |
119 profile_->GetPrefs(), | 131 profile_->GetPrefs(), |
120 ScreenlockBridge::Get())); | 132 ScreenlockBridge::Get())); |
121 } | 133 } |
122 return screenlock_state_handler_.get(); | 134 return screenlock_state_handler_.get(); |
123 } | 135 } |
124 | 136 |
| 137 const base::DictionaryValue* EasyUnlockService::GetPermitAccess() const { |
| 138 const base::DictionaryValue* pairing_dict = |
| 139 profile_->GetPrefs()->GetDictionary(prefs::kEasyUnlockPairing); |
| 140 const base::DictionaryValue* permit_dict = NULL; |
| 141 if (pairing_dict && |
| 142 pairing_dict->GetDictionary(kKeyPermitAccess, &permit_dict)) { |
| 143 return permit_dict; |
| 144 } |
| 145 |
| 146 return NULL; |
| 147 } |
| 148 |
| 149 void EasyUnlockService::SetPermitAccess(const base::DictionaryValue& permit) { |
| 150 DictionaryPrefUpdate pairing_update(profile_->GetPrefs(), |
| 151 prefs::kEasyUnlockPairing); |
| 152 pairing_update->SetWithoutPathExpansion(kKeyPermitAccess, permit.DeepCopy()); |
| 153 } |
| 154 |
| 155 void EasyUnlockService::ClearPermitAccess() { |
| 156 DictionaryPrefUpdate pairing_update(profile_->GetPrefs(), |
| 157 prefs::kEasyUnlockPairing); |
| 158 pairing_update->RemoveWithoutPathExpansion(kKeyPermitAccess, NULL); |
| 159 } |
| 160 |
| 161 const base::ListValue* EasyUnlockService::GetRemoteDevices() const { |
| 162 const base::DictionaryValue* pairing_dict = |
| 163 profile_->GetPrefs()->GetDictionary(prefs::kEasyUnlockPairing); |
| 164 const base::ListValue* devices = NULL; |
| 165 if (pairing_dict && pairing_dict->GetList(kKeyDevices, &devices)) { |
| 166 return devices; |
| 167 } |
| 168 |
| 169 return NULL; |
| 170 } |
| 171 |
| 172 void EasyUnlockService::SetRemoteDevices(const base::ListValue& devices) { |
| 173 DictionaryPrefUpdate pairing_update(profile_->GetPrefs(), |
| 174 prefs::kEasyUnlockPairing); |
| 175 pairing_update->SetWithoutPathExpansion(kKeyDevices, devices.DeepCopy()); |
| 176 } |
| 177 |
| 178 void EasyUnlockService::ClearRemoteDevices() { |
| 179 DictionaryPrefUpdate pairing_update(profile_->GetPrefs(), |
| 180 prefs::kEasyUnlockPairing); |
| 181 pairing_update->RemoveWithoutPathExpansion(kKeyDevices, NULL); |
| 182 } |
| 183 |
| 184 void EasyUnlockService::AddObserver(EasyUnlockServiceObserver* observer) { |
| 185 observers_.AddObserver(observer); |
| 186 } |
| 187 |
| 188 void EasyUnlockService::RemoveObserver(EasyUnlockServiceObserver* observer) { |
| 189 observers_.RemoveObserver(observer); |
| 190 } |
| 191 |
| 192 void EasyUnlockService::RunTurnOffFlow() { |
| 193 if (turn_off_flow_status_ == PENDING) |
| 194 return; |
| 195 |
| 196 SetTurnOffFlowStatus(PENDING); |
| 197 |
| 198 // Currently there should only be one registered phone. |
| 199 // TODO(xiyuan): Revisit this when server supports toggle for all or |
| 200 // there are multiple phones. |
| 201 const base::DictionaryValue* pairing_dict = |
| 202 profile_->GetPrefs()->GetDictionary(prefs::kEasyUnlockPairing); |
| 203 const base::ListValue* devices_list = NULL; |
| 204 const base::DictionaryValue* first_device = NULL; |
| 205 std::string phone_public_key; |
| 206 if (!pairing_dict || !pairing_dict->GetList(kKeyDevices, &devices_list) || |
| 207 !devices_list || !devices_list->GetDictionary(0, &first_device) || |
| 208 !first_device || |
| 209 !first_device->GetString(kKeyPhoneId, &phone_public_key)) { |
| 210 LOG(WARNING) << "Bad easy unlock pairing data, wiping out local data"; |
| 211 OnTurnOffFlowFinished(true); |
| 212 return; |
| 213 } |
| 214 |
| 215 turn_off_flow_.reset(new EasyUnlockToggleFlow( |
| 216 profile_, |
| 217 phone_public_key, |
| 218 false, |
| 219 base::Bind(&EasyUnlockService::OnTurnOffFlowFinished, |
| 220 base::Unretained(this)))); |
| 221 turn_off_flow_->Start(); |
| 222 } |
| 223 |
| 224 void EasyUnlockService::ResetTurnOffFlow() { |
| 225 turn_off_flow_.reset(); |
| 226 SetTurnOffFlowStatus(IDLE); |
| 227 } |
| 228 |
125 void EasyUnlockService::Initialize() { | 229 void EasyUnlockService::Initialize() { |
126 registrar_.Init(profile_->GetPrefs()); | 230 registrar_.Init(profile_->GetPrefs()); |
127 registrar_.Add( | 231 registrar_.Add( |
128 prefs::kEasyUnlockAllowed, | 232 prefs::kEasyUnlockAllowed, |
129 base::Bind(&EasyUnlockService::OnPrefsChanged, base::Unretained(this))); | 233 base::Bind(&EasyUnlockService::OnPrefsChanged, base::Unretained(this))); |
130 OnPrefsChanged(); | 234 OnPrefsChanged(); |
131 } | 235 } |
132 | 236 |
133 void EasyUnlockService::LoadApp() { | 237 void EasyUnlockService::LoadApp() { |
134 DCHECK(IsAllowed()); | 238 DCHECK(IsAllowed()); |
(...skipping 27 matching lines...) Expand all Loading... |
162 void EasyUnlockService::OnPrefsChanged() { | 266 void EasyUnlockService::OnPrefsChanged() { |
163 if (IsAllowed()) { | 267 if (IsAllowed()) { |
164 LoadApp(); | 268 LoadApp(); |
165 } else { | 269 } else { |
166 UnloadApp(); | 270 UnloadApp(); |
167 // Reset the screenlock state handler to make sure Screenlock state set | 271 // Reset the screenlock state handler to make sure Screenlock state set |
168 // by Easy Unlock app is reset. | 272 // by Easy Unlock app is reset. |
169 screenlock_state_handler_.reset(); | 273 screenlock_state_handler_.reset(); |
170 } | 274 } |
171 } | 275 } |
| 276 |
| 277 void EasyUnlockService::SetTurnOffFlowStatus(TurnOffFlowStatus status) { |
| 278 turn_off_flow_status_ = status; |
| 279 FOR_EACH_OBSERVER( |
| 280 EasyUnlockServiceObserver, observers_, OnTurnOffOperationStatusChanged()); |
| 281 } |
| 282 |
| 283 void EasyUnlockService::OnTurnOffFlowFinished(bool success) { |
| 284 turn_off_flow_.reset(); |
| 285 |
| 286 if (!success) { |
| 287 SetTurnOffFlowStatus(FAIL); |
| 288 return; |
| 289 } |
| 290 |
| 291 ClearRemoteDevices(); |
| 292 SetTurnOffFlowStatus(IDLE); |
| 293 |
| 294 if (GetComponentLoader(profile_)->Exists(extension_misc::kEasyUnlockAppId)) { |
| 295 extensions::ExtensionSystem* extension_system = |
| 296 extensions::ExtensionSystem::Get(profile_); |
| 297 extension_system->extension_service()->ReloadExtension( |
| 298 extension_misc::kEasyUnlockAppId); |
| 299 } |
| 300 } |
OLD | NEW |