Home | History | Annotate | Download | only in easy_unlock_private
      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 
     32 namespace extensions {
     33 namespace api {
     34 
     35 namespace {
     36 
     37 static base::LazyInstance<BrowserContextKeyedAPIFactory<EasyUnlockPrivateAPI> >
     38     g_factory = LAZY_INSTANCE_INITIALIZER;
     39 
     40 // Utility method for getting the API's crypto delegate.
     41 EasyUnlockPrivateCryptoDelegate* GetCryptoDelegate(
     42     content::BrowserContext* context) {
     43   return BrowserContextKeyedAPIFactory<EasyUnlockPrivateAPI>::Get(context)
     44              ->crypto_delegate();
     45 }
     46 
     47 EasyUnlockScreenlockStateHandler::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
     76 BrowserContextKeyedAPIFactory<EasyUnlockPrivateAPI>*
     77     EasyUnlockPrivateAPI::GetFactoryInstance() {
     78   return g_factory.Pointer();
     79 }
     80 
     81 EasyUnlockPrivateAPI::EasyUnlockPrivateAPI(content::BrowserContext* context)
     82     : crypto_delegate_(EasyUnlockPrivateCryptoDelegate::Create()) {
     83 }
     84 
     85 EasyUnlockPrivateAPI::~EasyUnlockPrivateAPI() {}
     86 
     87 EasyUnlockPrivateGetStringsFunction::EasyUnlockPrivateGetStringsFunction() {
     88 }
     89 EasyUnlockPrivateGetStringsFunction::~EasyUnlockPrivateGetStringsFunction() {
     90 }
     91 
     92 bool 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 (at) 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 
    290 EasyUnlockPrivatePerformECDHKeyAgreementFunction::
    291 EasyUnlockPrivatePerformECDHKeyAgreementFunction() {}
    292 
    293 EasyUnlockPrivatePerformECDHKeyAgreementFunction::
    294 ~EasyUnlockPrivatePerformECDHKeyAgreementFunction() {}
    295 
    296 bool 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 
    308 void 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 
    318 EasyUnlockPrivateGenerateEcP256KeyPairFunction::
    319 EasyUnlockPrivateGenerateEcP256KeyPairFunction() {}
    320 
    321 EasyUnlockPrivateGenerateEcP256KeyPairFunction::
    322 ~EasyUnlockPrivateGenerateEcP256KeyPairFunction() {}
    323 
    324 bool EasyUnlockPrivateGenerateEcP256KeyPairFunction::RunAsync() {
    325   GetCryptoDelegate(browser_context())->GenerateEcP256KeyPair(
    326       base::Bind(&EasyUnlockPrivateGenerateEcP256KeyPairFunction::OnData,
    327                  this));
    328   return true;
    329 }
    330 
    331 void 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 
    342 EasyUnlockPrivateCreateSecureMessageFunction::
    343 EasyUnlockPrivateCreateSecureMessageFunction() {}
    344 
    345 EasyUnlockPrivateCreateSecureMessageFunction::
    346 ~EasyUnlockPrivateCreateSecureMessageFunction() {}
    347 
    348 bool 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 
    360 void 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 
    370 EasyUnlockPrivateUnwrapSecureMessageFunction::
    371 EasyUnlockPrivateUnwrapSecureMessageFunction() {}
    372 
    373 EasyUnlockPrivateUnwrapSecureMessageFunction::
    374 ~EasyUnlockPrivateUnwrapSecureMessageFunction() {}
    375 
    376 bool 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 
    388 void 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 
    396 EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::
    397     EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction() {}
    398 
    399 EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::
    400     ~EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction() {}
    401 
    402 bool 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 
    420 void EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekSuccess() {
    421   SendResponse(true);
    422 }
    423 
    424 void EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekFailure(
    425     const std::string& error_message) {
    426   SetError(error_message);
    427   SendResponse(false);
    428 }
    429 
    430 EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
    431     EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
    432 
    433 EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
    434     ~EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
    435 
    436 void 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 
    450 EasyUnlockPrivateUpdateScreenlockStateFunction::
    451     EasyUnlockPrivateUpdateScreenlockStateFunction() {}
    452 
    453 EasyUnlockPrivateUpdateScreenlockStateFunction::
    454     ~EasyUnlockPrivateUpdateScreenlockStateFunction() {}
    455 
    456 bool 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 
    470 EasyUnlockPrivateSetPermitAccessFunction::
    471     EasyUnlockPrivateSetPermitAccessFunction() {
    472 }
    473 
    474 EasyUnlockPrivateSetPermitAccessFunction::
    475     ~EasyUnlockPrivateSetPermitAccessFunction() {
    476 }
    477 
    478 bool 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 
    490 EasyUnlockPrivateGetPermitAccessFunction::
    491     EasyUnlockPrivateGetPermitAccessFunction() {
    492 }
    493 
    494 EasyUnlockPrivateGetPermitAccessFunction::
    495     ~EasyUnlockPrivateGetPermitAccessFunction() {
    496 }
    497 
    498 bool 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 
    511 EasyUnlockPrivateClearPermitAccessFunction::
    512     EasyUnlockPrivateClearPermitAccessFunction() {
    513 }
    514 
    515 EasyUnlockPrivateClearPermitAccessFunction::
    516     ~EasyUnlockPrivateClearPermitAccessFunction() {
    517 }
    518 
    519 bool EasyUnlockPrivateClearPermitAccessFunction::RunSync() {
    520   Profile* profile = Profile::FromBrowserContext(browser_context());
    521   EasyUnlockService::Get(profile)->ClearPermitAccess();
    522   return true;
    523 }
    524 
    525 EasyUnlockPrivateSetRemoteDevicesFunction::
    526     EasyUnlockPrivateSetRemoteDevicesFunction() {
    527 }
    528 
    529 EasyUnlockPrivateSetRemoteDevicesFunction::
    530     ~EasyUnlockPrivateSetRemoteDevicesFunction() {
    531 }
    532 
    533 bool 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 
    552 EasyUnlockPrivateGetRemoteDevicesFunction::
    553     EasyUnlockPrivateGetRemoteDevicesFunction() {
    554 }
    555 
    556 EasyUnlockPrivateGetRemoteDevicesFunction::
    557     ~EasyUnlockPrivateGetRemoteDevicesFunction() {
    558 }
    559 
    560 bool 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 
    568 EasyUnlockPrivateGetSignInChallengeFunction::
    569     EasyUnlockPrivateGetSignInChallengeFunction() {
    570 }
    571 
    572 EasyUnlockPrivateGetSignInChallengeFunction::
    573     ~EasyUnlockPrivateGetSignInChallengeFunction() {
    574 }
    575 
    576 bool 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 
    587 EasyUnlockPrivateTrySignInSecretFunction::
    588     EasyUnlockPrivateTrySignInSecretFunction() {
    589 }
    590 
    591 EasyUnlockPrivateTrySignInSecretFunction::
    592     ~EasyUnlockPrivateTrySignInSecretFunction() {
    593 }
    594 
    595 bool 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 
    605 EasyUnlockPrivateGetUserInfoFunction::EasyUnlockPrivateGetUserInfoFunction() {
    606 }
    607 
    608 EasyUnlockPrivateGetUserInfoFunction::~EasyUnlockPrivateGetUserInfoFunction() {
    609 }
    610 
    611 bool 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