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/extensions/api/easy_unlock_private/easy_unlock_private_api.h"
6
7#include <vector>
8
9#include "base/bind.h"
10#include "base/lazy_instance.h"
11#include "base/memory/linked_ptr.h"
12#include "base/strings/utf_string_conversions.h"
13#include "base/values.h"
14#include "chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_crypto_delegate.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/signin/easy_unlock_screenlock_state_handler.h"
17#include "chrome/browser/signin/easy_unlock_service.h"
18#include "chrome/browser/signin/screenlock_bridge.h"
19#include "chrome/common/extensions/api/easy_unlock_private.h"
20#include "chrome/grit/generated_resources.h"
21#include "components/proximity_auth/bluetooth_util.h"
22#include "content/public/browser/browser_thread.h"
23#include "extensions/browser/browser_context_keyed_api_factory.h"
24#include "ui/base/l10n/l10n_util.h"
25
26#if defined(OS_CHROMEOS)
27#include "chrome/browser/chromeos/chromeos_utils.h"
28#include "components/user_manager/user.h"
29#include "components/user_manager/user_manager.h"
30#endif
31
32namespace extensions {
33namespace api {
34
35namespace {
36
37static base::LazyInstance<BrowserContextKeyedAPIFactory<EasyUnlockPrivateAPI> >
38    g_factory = LAZY_INSTANCE_INITIALIZER;
39
40// Utility method for getting the API's crypto delegate.
41EasyUnlockPrivateCryptoDelegate* GetCryptoDelegate(
42    content::BrowserContext* context) {
43  return BrowserContextKeyedAPIFactory<EasyUnlockPrivateAPI>::Get(context)
44             ->crypto_delegate();
45}
46
47EasyUnlockScreenlockStateHandler::State ToScreenlockStateHandlerState(
48    easy_unlock_private::State state) {
49  switch (state) {
50    case easy_unlock_private::STATE_NO_BLUETOOTH:
51      return EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH;
52    case easy_unlock_private::STATE_BLUETOOTH_CONNECTING:
53      return EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING;
54    case easy_unlock_private::STATE_NO_PHONE:
55      return EasyUnlockScreenlockStateHandler::STATE_NO_PHONE;
56    case easy_unlock_private::STATE_PHONE_NOT_AUTHENTICATED:
57      return EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED;
58    case easy_unlock_private::STATE_PHONE_LOCKED:
59      return EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED;
60    case easy_unlock_private::STATE_PHONE_UNLOCKABLE:
61      return EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE;
62    case easy_unlock_private::STATE_PHONE_NOT_NEARBY:
63      return EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY;
64    case easy_unlock_private::STATE_PHONE_UNSUPPORTED:
65      return EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED;
66    case easy_unlock_private::STATE_AUTHENTICATED:
67      return EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED;
68    default:
69      return EasyUnlockScreenlockStateHandler::STATE_INACTIVE;
70  }
71}
72
73}  // namespace
74
75// static
76BrowserContextKeyedAPIFactory<EasyUnlockPrivateAPI>*
77    EasyUnlockPrivateAPI::GetFactoryInstance() {
78  return g_factory.Pointer();
79}
80
81EasyUnlockPrivateAPI::EasyUnlockPrivateAPI(content::BrowserContext* context)
82    : crypto_delegate_(EasyUnlockPrivateCryptoDelegate::Create()) {
83}
84
85EasyUnlockPrivateAPI::~EasyUnlockPrivateAPI() {}
86
87EasyUnlockPrivateGetStringsFunction::EasyUnlockPrivateGetStringsFunction() {
88}
89EasyUnlockPrivateGetStringsFunction::~EasyUnlockPrivateGetStringsFunction() {
90}
91
92bool EasyUnlockPrivateGetStringsFunction::RunSync() {
93  scoped_ptr<base::DictionaryValue> strings(new base::DictionaryValue);
94
95#if defined(OS_CHROMEOS)
96  const base::string16 device_type = chromeos::GetChromeDeviceType();
97#else
98  // TODO(isherman): Set an appropriate device name for non-ChromeOS devices.
99  const base::string16 device_type = base::ASCIIToUTF16("Chromeschnozzle");
100#endif  // defined(OS_CHROMEOS)
101
102#if defined(OS_CHROMEOS)
103  const user_manager::UserManager* manager = user_manager::UserManager::Get();
104  const user_manager::User* user = manager ? manager->GetActiveUser() : NULL;
105  const std::string user_email_utf8 =
106      user ? user->display_email() : std::string();
107  const base::string16 user_email = base::UTF8ToUTF16(user_email_utf8);
108#else
109  // TODO(isherman): Set an appropriate user display email for non-ChromeOS
110  // platforms.
111  const base::string16 user_email = base::UTF8ToUTF16("superman@example.com");
112#endif  // defined(OS_CHROMEOS)
113
114  // Common strings.
115  strings->SetString(
116      "learnMoreLinkTitle",
117      l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_LEARN_MORE_LINK_TITLE));
118  strings->SetString("deviceType", device_type);
119
120  // Setup notification strings.
121  strings->SetString(
122      "setupNotificationTitle",
123      l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_NOTIFICATION_TITLE,
124                                 device_type));
125  strings->SetString(
126      "setupNotificationMessage",
127      l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_NOTIFICATION_MESSAGE,
128                                 device_type));
129  strings->SetString(
130      "setupNotificationButtonTitle",
131      l10n_util::GetStringUTF16(
132          IDS_EASY_UNLOCK_SETUP_NOTIFICATION_BUTTON_TITLE));
133
134  // Success notification strings.
135  strings->SetString(
136      "successNotificationTitle",
137      l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SUCCESS_NOTIFICATION_TITLE));
138  strings->SetString(
139      "successNotificationMessage",
140      l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SUCCESS_NOTIFICATION_MESSAGE,
141                                 device_type));
142
143  // Chromebook added to Easy Unlock notification strings.
144  strings->SetString(
145      "chromebookAddedNotificationTitle",
146      l10n_util::GetStringUTF16(
147          IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_TITLE));
148  strings->SetString(
149      "chromebookAddedNotificationMessage",
150      l10n_util::GetStringFUTF16(
151          IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_MESSAGE,
152          device_type));
153  strings->SetString(
154      "chromebookAddedNotificationAboutButton",
155      l10n_util::GetStringUTF16(
156          IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_ABOUT_BUTTON));
157
158  // Shared "Learn more" button for the pairing changed and pairing change
159  // applied notification.
160  strings->SetString(
161      "phoneChangedNotificationLearnMoreButton",
162      l10n_util::GetStringUTF16(
163          IDS_EASY_UNLOCK_NOTIFICATION_LEARN_MORE_BUTTON));
164
165  // Pairing changed notification strings.
166  strings->SetString(
167      "phoneChangedNotificationTitle",
168      l10n_util::GetStringUTF16(
169          IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_TITLE));
170  strings->SetString(
171      "phoneChangedNotificationMessage",
172      l10n_util::GetStringFUTF16(
173          IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_MESSAGE,
174          device_type));
175  strings->SetString(
176      "phoneChangedNotificationUpdateButton",
177      l10n_util::GetStringUTF16(
178          IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_UPDATE_BUTTON));
179
180  // Phone change applied notification strings.
181  strings->SetString(
182      "phoneChangeAppliedNotificationTitle",
183      l10n_util::GetStringUTF16(
184          IDS_EASY_UNLOCK_PAIRING_CHANGE_APPLIED_NOTIFICATION_TITLE));
185  strings->SetString(
186      "phoneChangeAppliedNotificationMessage",
187      l10n_util::GetStringUTF16(
188          IDS_EASY_UNLOCK_PAIRING_CHANGE_APPLIED_NOTIFICATION_MESSAGE));
189
190  // Setup dialog strings.
191  // Step 1: Intro.
192  strings->SetString(
193      "setupIntroHeaderTitle",
194      l10n_util::GetStringFUTF16(
195          IDS_EASY_UNLOCK_SETUP_INTRO_HEADER_TITLE, device_type));
196  strings->SetString(
197      "setupIntroHeaderText",
198      l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_INTRO_HEADER_TEXT,
199                                 device_type,
200                                 user_email));
201  strings->SetString(
202      "setupIntroFindPhoneButtonLabel",
203      l10n_util::GetStringUTF16(
204          IDS_EASY_UNLOCK_SETUP_INTRO_FIND_PHONE_BUTTON_LABEL));
205  strings->SetString(
206      "setupIntroFindingPhoneButtonLabel",
207      l10n_util::GetStringUTF16(
208          IDS_EASY_UNLOCK_SETUP_INTRO_FINDING_PHONE_BUTTON_LABEL));
209  strings->SetString(
210      "setupIntroRetryFindPhoneButtonLabel",
211      l10n_util::GetStringUTF16(
212          IDS_EASY_UNLOCK_SETUP_INTRO_RETRY_FIND_PHONE_BUTTON_LABEL));
213  strings->SetString(
214      "setupIntroHowIsThisSecureLinkText",
215      l10n_util::GetStringUTF16(
216          IDS_EASY_UNLOCK_SETUP_INTRO_HOW_IS_THIS_SECURE_LINK_TEXT));
217  // Step 2: Found a viable phone.
218  strings->SetString(
219      "setupFoundPhoneHeaderTitle",
220      l10n_util::GetStringFUTF16(
221          IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_HEADER_TITLE, device_type));
222  strings->SetString(
223      "setupFoundPhoneHeaderText",
224      l10n_util::GetStringFUTF16(
225          IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_HEADER_TEXT, device_type));
226  strings->SetString(
227      "setupFoundPhoneUseThisPhoneButtonLabel",
228      l10n_util::GetStringUTF16(
229          IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_USE_THIS_PHONE_BUTTON_LABEL));
230  strings->SetString(
231      "setupPairingPhoneFailedButtonLabel",
232      l10n_util::GetStringUTF16(
233          IDS_EASY_UNLOCK_SETUP_PAIRING_PHONE_FAILED_BUTTON_LABEL));
234  // Step 3: Setup completed successfully.
235  strings->SetString(
236      "setupCompleteHeaderTitle",
237      l10n_util::GetStringUTF16(
238          IDS_EASY_UNLOCK_SETUP_COMPLETE_HEADER_TITLE));
239  strings->SetString(
240      "setupCompleteHeaderText",
241      l10n_util::GetStringUTF16(
242          IDS_EASY_UNLOCK_SETUP_COMPLETE_HEADER_TEXT));
243  strings->SetString(
244      "setupCompleteTryItOutButtonLabel",
245      l10n_util::GetStringUTF16(
246          IDS_EASY_UNLOCK_SETUP_COMPLETE_TRY_IT_OUT_BUTTON_LABEL));
247  strings->SetString(
248      "setupCompleteSettingsLinkText",
249      l10n_util::GetStringUTF16(
250          IDS_EASY_UNLOCK_SETUP_COMPLETE_SETTINGS_LINK_TEXT));
251
252  // Error strings.
253  strings->SetString(
254      "setupErrorBluetoothUnavailable",
255      l10n_util::GetStringFUTF16(
256          IDS_EASY_UNLOCK_SETUP_ERROR_BLUETOOTH_UNAVAILBLE, device_type));
257  strings->SetString(
258      "setupErrorOffline",
259      l10n_util::GetStringFUTF16(
260          IDS_EASY_UNLOCK_SETUP_ERROR_OFFLINE, device_type));
261  strings->SetString(
262      "setupErrorFindingPhone",
263      l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SETUP_ERROR_FINDING_PHONE));
264  strings->SetString(
265      "setupErrorBluetoothConnectionFailed",
266      l10n_util::GetStringFUTF16(
267          IDS_EASY_UNLOCK_SETUP_ERROR_BLUETOOTH_CONNECTION_FAILED,
268          device_type));
269  strings->SetString(
270      "setupErrorConnectionToPhoneTimeout",
271       l10n_util::GetStringFUTF16(
272           IDS_EASY_UNLOCK_SETUP_ERROR_CONNECT_TO_PHONE_TIMEOUT,
273           device_type));
274  strings->SetString(
275      "setupErrorSyncPhoneState",
276       l10n_util::GetStringUTF16(
277           IDS_EASY_UNLOCK_SETUP_ERROR_SYNC_PHONE_STATE_FAILED));
278  strings->SetString(
279      "setupErrorConnectingToPhone",
280      l10n_util::GetStringFUTF16(
281          IDS_EASY_UNLOCK_SETUP_ERROR_CONNECTING_TO_PHONE, device_type));
282
283  // TODO(isherman): Remove this string once the app has been updated.
284  strings->SetString("setupIntroHeaderFootnote", base::string16());
285
286  SetResult(strings.release());
287  return true;
288}
289
290EasyUnlockPrivatePerformECDHKeyAgreementFunction::
291EasyUnlockPrivatePerformECDHKeyAgreementFunction() {}
292
293EasyUnlockPrivatePerformECDHKeyAgreementFunction::
294~EasyUnlockPrivatePerformECDHKeyAgreementFunction() {}
295
296bool EasyUnlockPrivatePerformECDHKeyAgreementFunction::RunAsync() {
297  scoped_ptr<easy_unlock_private::PerformECDHKeyAgreement::Params> params =
298      easy_unlock_private::PerformECDHKeyAgreement::Params::Create(*args_);
299  EXTENSION_FUNCTION_VALIDATE(params);
300
301  GetCryptoDelegate(browser_context())->PerformECDHKeyAgreement(
302      *params,
303      base::Bind(&EasyUnlockPrivatePerformECDHKeyAgreementFunction::OnData,
304                 this));
305  return true;
306}
307
308void EasyUnlockPrivatePerformECDHKeyAgreementFunction::OnData(
309    const std::string& secret_key) {
310  // TODO(tbarzic): Improve error handling.
311  if (!secret_key.empty()) {
312    results_ = easy_unlock_private::PerformECDHKeyAgreement::Results::Create(
313        secret_key);
314  }
315  SendResponse(true);
316}
317
318EasyUnlockPrivateGenerateEcP256KeyPairFunction::
319EasyUnlockPrivateGenerateEcP256KeyPairFunction() {}
320
321EasyUnlockPrivateGenerateEcP256KeyPairFunction::
322~EasyUnlockPrivateGenerateEcP256KeyPairFunction() {}
323
324bool EasyUnlockPrivateGenerateEcP256KeyPairFunction::RunAsync() {
325  GetCryptoDelegate(browser_context())->GenerateEcP256KeyPair(
326      base::Bind(&EasyUnlockPrivateGenerateEcP256KeyPairFunction::OnData,
327                 this));
328  return true;
329}
330
331void EasyUnlockPrivateGenerateEcP256KeyPairFunction::OnData(
332    const std::string& private_key,
333    const std::string& public_key) {
334  // TODO(tbarzic): Improve error handling.
335  if (!public_key.empty() && !private_key.empty()) {
336    results_ = easy_unlock_private::GenerateEcP256KeyPair::Results::Create(
337        public_key, private_key);
338  }
339  SendResponse(true);
340}
341
342EasyUnlockPrivateCreateSecureMessageFunction::
343EasyUnlockPrivateCreateSecureMessageFunction() {}
344
345EasyUnlockPrivateCreateSecureMessageFunction::
346~EasyUnlockPrivateCreateSecureMessageFunction() {}
347
348bool EasyUnlockPrivateCreateSecureMessageFunction::RunAsync() {
349  scoped_ptr<easy_unlock_private::CreateSecureMessage::Params> params =
350      easy_unlock_private::CreateSecureMessage::Params::Create(*args_);
351  EXTENSION_FUNCTION_VALIDATE(params);
352
353  GetCryptoDelegate(browser_context())->CreateSecureMessage(
354      *params,
355      base::Bind(&EasyUnlockPrivateCreateSecureMessageFunction::OnData,
356                 this));
357  return true;
358}
359
360void EasyUnlockPrivateCreateSecureMessageFunction::OnData(
361    const std::string& message) {
362  // TODO(tbarzic): Improve error handling.
363  if (!message.empty()) {
364    results_ = easy_unlock_private::CreateSecureMessage::Results::Create(
365        message);
366  }
367  SendResponse(true);
368}
369
370EasyUnlockPrivateUnwrapSecureMessageFunction::
371EasyUnlockPrivateUnwrapSecureMessageFunction() {}
372
373EasyUnlockPrivateUnwrapSecureMessageFunction::
374~EasyUnlockPrivateUnwrapSecureMessageFunction() {}
375
376bool EasyUnlockPrivateUnwrapSecureMessageFunction::RunAsync() {
377  scoped_ptr<easy_unlock_private::UnwrapSecureMessage::Params> params =
378      easy_unlock_private::UnwrapSecureMessage::Params::Create(*args_);
379  EXTENSION_FUNCTION_VALIDATE(params);
380
381  GetCryptoDelegate(browser_context())->UnwrapSecureMessage(
382      *params,
383      base::Bind(&EasyUnlockPrivateUnwrapSecureMessageFunction::OnData,
384                 this));
385  return true;
386}
387
388void EasyUnlockPrivateUnwrapSecureMessageFunction::OnData(
389    const std::string& data) {
390  // TODO(tbarzic): Improve error handling.
391  if (!data.empty())
392    results_ = easy_unlock_private::UnwrapSecureMessage::Results::Create(data);
393  SendResponse(true);
394}
395
396EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::
397    EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction() {}
398
399EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::
400    ~EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction() {}
401
402bool EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::RunAsync() {
403  scoped_ptr<easy_unlock_private::SeekBluetoothDeviceByAddress::Params> params(
404      easy_unlock_private::SeekBluetoothDeviceByAddress::Params::Create(
405          *args_));
406  EXTENSION_FUNCTION_VALIDATE(params.get());
407
408  proximity_auth::bluetooth_util::SeekDeviceByAddress(
409      params->device_address,
410      base::Bind(
411          &EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekSuccess,
412          this),
413      base::Bind(
414          &EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekFailure,
415          this),
416      content::BrowserThread::GetBlockingPool());
417  return true;
418}
419
420void EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekSuccess() {
421  SendResponse(true);
422}
423
424void EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekFailure(
425    const std::string& error_message) {
426  SetError(error_message);
427  SendResponse(false);
428}
429
430EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
431    EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
432
433EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
434    ~EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
435
436void EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
437    ConnectToService(device::BluetoothDevice* device,
438                     const device::BluetoothUUID& uuid) {
439  proximity_auth::bluetooth_util::ConnectToServiceInsecurely(
440      device,
441      uuid,
442      base::Bind(&EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
443                     OnConnect,
444                 this),
445      base::Bind(&EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
446                     OnConnectError,
447                 this));
448}
449
450EasyUnlockPrivateUpdateScreenlockStateFunction::
451    EasyUnlockPrivateUpdateScreenlockStateFunction() {}
452
453EasyUnlockPrivateUpdateScreenlockStateFunction::
454    ~EasyUnlockPrivateUpdateScreenlockStateFunction() {}
455
456bool EasyUnlockPrivateUpdateScreenlockStateFunction::RunSync() {
457  scoped_ptr<easy_unlock_private::UpdateScreenlockState::Params> params(
458      easy_unlock_private::UpdateScreenlockState::Params::Create(*args_));
459  EXTENSION_FUNCTION_VALIDATE(params.get());
460
461  Profile* profile = Profile::FromBrowserContext(browser_context());
462  if (EasyUnlockService::Get(profile)->UpdateScreenlockState(
463          ToScreenlockStateHandlerState(params->state)))
464    return true;
465
466  SetError("Not allowed");
467  return false;
468}
469
470EasyUnlockPrivateSetPermitAccessFunction::
471    EasyUnlockPrivateSetPermitAccessFunction() {
472}
473
474EasyUnlockPrivateSetPermitAccessFunction::
475    ~EasyUnlockPrivateSetPermitAccessFunction() {
476}
477
478bool EasyUnlockPrivateSetPermitAccessFunction::RunSync() {
479  scoped_ptr<easy_unlock_private::SetPermitAccess::Params> params(
480      easy_unlock_private::SetPermitAccess::Params::Create(*args_));
481  EXTENSION_FUNCTION_VALIDATE(params.get());
482
483  Profile* profile = Profile::FromBrowserContext(browser_context());
484  EasyUnlockService::Get(profile)
485      ->SetPermitAccess(*params->permit_access.ToValue());
486
487  return true;
488}
489
490EasyUnlockPrivateGetPermitAccessFunction::
491    EasyUnlockPrivateGetPermitAccessFunction() {
492}
493
494EasyUnlockPrivateGetPermitAccessFunction::
495    ~EasyUnlockPrivateGetPermitAccessFunction() {
496}
497
498bool EasyUnlockPrivateGetPermitAccessFunction::RunSync() {
499  Profile* profile = Profile::FromBrowserContext(browser_context());
500  const base::DictionaryValue* permit_value =
501      EasyUnlockService::Get(profile)->GetPermitAccess();
502  if (permit_value) {
503    scoped_ptr<easy_unlock_private::PermitRecord> permit =
504        easy_unlock_private::PermitRecord::FromValue(*permit_value);
505    results_ = easy_unlock_private::GetPermitAccess::Results::Create(*permit);
506  }
507
508  return true;
509}
510
511EasyUnlockPrivateClearPermitAccessFunction::
512    EasyUnlockPrivateClearPermitAccessFunction() {
513}
514
515EasyUnlockPrivateClearPermitAccessFunction::
516    ~EasyUnlockPrivateClearPermitAccessFunction() {
517}
518
519bool EasyUnlockPrivateClearPermitAccessFunction::RunSync() {
520  Profile* profile = Profile::FromBrowserContext(browser_context());
521  EasyUnlockService::Get(profile)->ClearPermitAccess();
522  return true;
523}
524
525EasyUnlockPrivateSetRemoteDevicesFunction::
526    EasyUnlockPrivateSetRemoteDevicesFunction() {
527}
528
529EasyUnlockPrivateSetRemoteDevicesFunction::
530    ~EasyUnlockPrivateSetRemoteDevicesFunction() {
531}
532
533bool EasyUnlockPrivateSetRemoteDevicesFunction::RunSync() {
534  scoped_ptr<easy_unlock_private::SetRemoteDevices::Params> params(
535      easy_unlock_private::SetRemoteDevices::Params::Create(*args_));
536  EXTENSION_FUNCTION_VALIDATE(params.get());
537
538  Profile* profile = Profile::FromBrowserContext(browser_context());
539  if (params->devices.empty()) {
540    EasyUnlockService::Get(profile)->ClearRemoteDevices();
541  } else {
542    base::ListValue devices;
543    for (size_t i = 0; i < params->devices.size(); ++i) {
544      devices.Append(params->devices[i]->ToValue().release());
545    }
546    EasyUnlockService::Get(profile)->SetRemoteDevices(devices);
547  }
548
549  return true;
550}
551
552EasyUnlockPrivateGetRemoteDevicesFunction::
553    EasyUnlockPrivateGetRemoteDevicesFunction() {
554}
555
556EasyUnlockPrivateGetRemoteDevicesFunction::
557    ~EasyUnlockPrivateGetRemoteDevicesFunction() {
558}
559
560bool EasyUnlockPrivateGetRemoteDevicesFunction::RunSync() {
561  Profile* profile = Profile::FromBrowserContext(browser_context());
562  const base::ListValue* devices =
563      EasyUnlockService::Get(profile)->GetRemoteDevices();
564  SetResult(devices ? devices->DeepCopy() : new base::ListValue());
565  return true;
566}
567
568EasyUnlockPrivateGetSignInChallengeFunction::
569    EasyUnlockPrivateGetSignInChallengeFunction() {
570}
571
572EasyUnlockPrivateGetSignInChallengeFunction::
573    ~EasyUnlockPrivateGetSignInChallengeFunction() {
574}
575
576bool EasyUnlockPrivateGetSignInChallengeFunction::RunSync() {
577  Profile* profile = Profile::FromBrowserContext(browser_context());
578  const std::string challenge =
579      EasyUnlockService::Get(profile)->GetChallenge();
580  if (!challenge.empty()) {
581    results_ =
582        easy_unlock_private::GetSignInChallenge::Results::Create(challenge);
583  }
584  return true;
585}
586
587EasyUnlockPrivateTrySignInSecretFunction::
588    EasyUnlockPrivateTrySignInSecretFunction() {
589}
590
591EasyUnlockPrivateTrySignInSecretFunction::
592    ~EasyUnlockPrivateTrySignInSecretFunction() {
593}
594
595bool EasyUnlockPrivateTrySignInSecretFunction::RunSync() {
596  scoped_ptr<easy_unlock_private::TrySignInSecret::Params> params(
597      easy_unlock_private::TrySignInSecret::Params::Create(*args_));
598  EXTENSION_FUNCTION_VALIDATE(params.get());
599
600  Profile* profile = Profile::FromBrowserContext(browser_context());
601  EasyUnlockService::Get(profile)->FinalizeSignin(params->sign_in_secret);
602  return true;
603}
604
605EasyUnlockPrivateGetUserInfoFunction::EasyUnlockPrivateGetUserInfoFunction() {
606}
607
608EasyUnlockPrivateGetUserInfoFunction::~EasyUnlockPrivateGetUserInfoFunction() {
609}
610
611bool EasyUnlockPrivateGetUserInfoFunction::RunSync() {
612  EasyUnlockService* service =
613      EasyUnlockService::Get(Profile::FromBrowserContext(browser_context()));
614  std::vector<linked_ptr<easy_unlock_private::UserInfo> > users;
615  std::string user_id = service->GetUserEmail();
616  if (!user_id.empty()) {
617    users.push_back(
618        linked_ptr<easy_unlock_private::UserInfo>(
619            new easy_unlock_private::UserInfo()));
620    users[0]->user_id = user_id;
621    users[0]->logged_in = service->GetType() == EasyUnlockService::TYPE_REGULAR;
622    users[0]->data_ready = users[0]->logged_in ||
623                           service->GetRemoteDevices() != NULL;
624  }
625  results_ = easy_unlock_private::GetUserInfo::Results::Create(users);
626  return true;
627}
628
629}  // namespace api
630}  // namespace extensions
631