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.
5 #include "chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h"
10 #include "base/command_line.h"
11 #include "base/lazy_instance.h"
12 #include "base/memory/linked_ptr.h"
13 #include "base/numerics/safe_conversions.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "base/time/default_tick_clock.h"
17 #include "base/time/time.h"
18 #include "base/timer/timer.h"
19 #include "base/values.h"
20 #include "chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.h"
21 #include "chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_crypto_delegate.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/signin/easy_unlock_screenlock_state_handler.h"
24 #include "chrome/browser/signin/easy_unlock_service.h"
25 #include "chrome/browser/signin/easy_unlock_service_regular.h"
26 #include "chrome/browser/ui/proximity_auth/proximity_auth_error_bubble.h"
27 #include "chrome/common/extensions/api/easy_unlock_private.h"
28 #include "chrome/grit/generated_resources.h"
29 #include "components/proximity_auth/ble/bluetooth_low_energy_connection.h"
30 #include "components/proximity_auth/ble/bluetooth_low_energy_connection_finder.h"
31 #include "components/proximity_auth/bluetooth_throttler_impl.h"
32 #include "components/proximity_auth/bluetooth_util.h"
33 #include "components/proximity_auth/cryptauth/base64url.h"
34 #include "components/proximity_auth/cryptauth/cryptauth_device_manager.h"
35 #include "components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h"
36 #include "components/proximity_auth/cryptauth/cryptauth_enrollment_utils.h"
37 #include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h"
38 #include "components/proximity_auth/cryptauth/secure_message_delegate.h"
39 #include "components/proximity_auth/logging/logging.h"
40 #include "components/proximity_auth/proximity_auth_client.h"
41 #include "components/proximity_auth/remote_device.h"
42 #include "components/proximity_auth/screenlock_bridge.h"
43 #include "components/proximity_auth/screenlock_state.h"
44 #include "components/proximity_auth/switches.h"
45 #include "content/public/browser/browser_thread.h"
46 #include "content/public/browser/web_contents.h"
47 #include "extensions/browser/browser_context_keyed_api_factory.h"
48 #include "ui/base/l10n/l10n_util.h"
49 #include "ui/gfx/geometry/rect.h"
50 #include "ui/gfx/range/range.h"
52 #if defined(OS_CHROMEOS)
53 #include "ash/system/chromeos/devicetype_utils.h"
54 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.h"
55 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.h"
56 #include "components/user_manager/user.h"
57 #include "components/user_manager/user_manager.h"
60 using proximity_auth::ScreenlockState
;
62 namespace extensions
{
64 namespace easy_unlock_private
= api::easy_unlock_private
;
68 static base::LazyInstance
<BrowserContextKeyedAPIFactory
<EasyUnlockPrivateAPI
> >
69 g_factory
= LAZY_INSTANCE_INITIALIZER
;
71 // Utility method for getting the API's crypto delegate.
72 EasyUnlockPrivateCryptoDelegate
* GetCryptoDelegate(
73 content::BrowserContext
* context
) {
74 return BrowserContextKeyedAPIFactory
<EasyUnlockPrivateAPI
>::Get(context
)
75 ->GetCryptoDelegate();
78 EasyUnlockPrivateConnectionManager
* GetConnectionManager(
79 content::BrowserContext
* context
) {
80 return BrowserContextKeyedAPIFactory
<EasyUnlockPrivateAPI
>::Get(context
)
81 ->get_connection_manager();
84 ScreenlockState
ToScreenlockState(easy_unlock_private::State state
) {
86 case easy_unlock_private::STATE_NO_BLUETOOTH
:
87 return ScreenlockState::NO_BLUETOOTH
;
88 case easy_unlock_private::STATE_BLUETOOTH_CONNECTING
:
89 return ScreenlockState::BLUETOOTH_CONNECTING
;
90 case easy_unlock_private::STATE_NO_PHONE
:
91 return ScreenlockState::NO_PHONE
;
92 case easy_unlock_private::STATE_PHONE_NOT_AUTHENTICATED
:
93 return ScreenlockState::PHONE_NOT_AUTHENTICATED
;
94 case easy_unlock_private::STATE_PHONE_LOCKED
:
95 return ScreenlockState::PHONE_LOCKED
;
96 case easy_unlock_private::STATE_PHONE_UNLOCKABLE
:
97 return ScreenlockState::PHONE_NOT_LOCKABLE
;
98 case easy_unlock_private::STATE_PHONE_UNSUPPORTED
:
99 return ScreenlockState::PHONE_UNSUPPORTED
;
100 case easy_unlock_private::STATE_RSSI_TOO_LOW
:
101 return ScreenlockState::RSSI_TOO_LOW
;
102 case easy_unlock_private::STATE_TX_POWER_TOO_HIGH
:
103 return ScreenlockState::TX_POWER_TOO_HIGH
;
104 case easy_unlock_private::STATE_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH
:
105 return ScreenlockState::PHONE_LOCKED_AND_TX_POWER_TOO_HIGH
;
106 case easy_unlock_private::STATE_AUTHENTICATED
:
107 return ScreenlockState::AUTHENTICATED
;
109 return ScreenlockState::INACTIVE
;
116 BrowserContextKeyedAPIFactory
<EasyUnlockPrivateAPI
>*
117 EasyUnlockPrivateAPI::GetFactoryInstance() {
118 return g_factory
.Pointer();
121 EasyUnlockPrivateAPI::EasyUnlockPrivateAPI(content::BrowserContext
* context
)
122 : connection_manager_(new EasyUnlockPrivateConnectionManager(context
)) {}
124 EasyUnlockPrivateAPI::~EasyUnlockPrivateAPI() {}
126 EasyUnlockPrivateCryptoDelegate
* EasyUnlockPrivateAPI::GetCryptoDelegate() {
127 if (!crypto_delegate_
)
128 crypto_delegate_
= EasyUnlockPrivateCryptoDelegate::Create();
129 return crypto_delegate_
.get();
132 EasyUnlockPrivateGetStringsFunction::EasyUnlockPrivateGetStringsFunction() {
134 EasyUnlockPrivateGetStringsFunction::~EasyUnlockPrivateGetStringsFunction() {
137 bool EasyUnlockPrivateGetStringsFunction::RunSync() {
138 scoped_ptr
<base::DictionaryValue
> strings(new base::DictionaryValue
);
140 #if defined(OS_CHROMEOS)
141 const base::string16 device_type
= ash::GetChromeOSDeviceName();
143 // TODO(isherman): Set an appropriate device name for non-ChromeOS devices.
144 const base::string16 device_type
= base::ASCIIToUTF16("Chromeschnozzle");
145 #endif // defined(OS_CHROMEOS)
147 #if defined(OS_CHROMEOS)
148 const user_manager::UserManager
* manager
= user_manager::UserManager::Get();
149 const user_manager::User
* user
= manager
? manager
->GetActiveUser() : NULL
;
150 const std::string user_email_utf8
=
151 user
? user
->display_email() : std::string();
152 const base::string16 user_email
= base::UTF8ToUTF16(user_email_utf8
);
154 // TODO(isherman): Set an appropriate user display email for non-ChromeOS
156 const base::string16 user_email
= base::UTF8ToUTF16("superman@example.com");
157 #endif // defined(OS_CHROMEOS)
161 "learnMoreLinkTitle",
162 l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_LEARN_MORE_LINK_TITLE
));
163 strings
->SetString("deviceType", device_type
);
165 // Setup notification strings.
167 "setupNotificationTitle",
168 l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SETUP_NOTIFICATION_TITLE
));
170 "setupNotificationMessage",
171 l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_NOTIFICATION_MESSAGE
,
174 "setupNotificationButtonTitle",
175 l10n_util::GetStringUTF16(
176 IDS_EASY_UNLOCK_SETUP_NOTIFICATION_BUTTON_TITLE
));
178 // Chromebook added to Easy Unlock notification strings.
180 "chromebookAddedNotificationTitle",
181 l10n_util::GetStringUTF16(
182 IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_TITLE
));
184 "chromebookAddedNotificationMessage",
185 l10n_util::GetStringFUTF16(
186 IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_MESSAGE
,
189 "chromebookAddedNotificationAboutButton",
190 l10n_util::GetStringUTF16(
191 IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_ABOUT_BUTTON
));
193 // Shared "Learn more" button for the pairing changed and pairing change
194 // applied notification.
196 "phoneChangedNotificationLearnMoreButton",
197 l10n_util::GetStringUTF16(
198 IDS_EASY_UNLOCK_NOTIFICATION_LEARN_MORE_BUTTON
));
200 // Pairing changed notification strings.
202 "phoneChangedNotificationTitle",
203 l10n_util::GetStringUTF16(
204 IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_TITLE
));
206 "phoneChangedNotificationMessage",
207 l10n_util::GetStringFUTF16(
208 IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_MESSAGE
,
211 "phoneChangedNotificationUpdateButton",
212 l10n_util::GetStringUTF16(
213 IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_UPDATE_BUTTON
));
215 // Phone change applied notification strings.
217 "phoneChangeAppliedNotificationTitle",
218 l10n_util::GetStringUTF16(
219 IDS_EASY_UNLOCK_PAIRING_CHANGE_APPLIED_NOTIFICATION_TITLE
));
221 "phoneChangeAppliedNotificationMessage",
222 l10n_util::GetStringUTF16(
223 IDS_EASY_UNLOCK_PAIRING_CHANGE_APPLIED_NOTIFICATION_MESSAGE
));
225 // Setup dialog strings.
228 "setupIntroHeaderTitle",
229 l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SETUP_INTRO_HEADER_TITLE
));
231 "setupIntroHeaderText",
232 l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_INTRO_HEADER_TEXT
,
236 "setupIntroFindPhoneButtonLabel",
237 l10n_util::GetStringUTF16(
238 IDS_EASY_UNLOCK_SETUP_INTRO_FIND_PHONE_BUTTON_LABEL
));
240 "setupIntroFindingPhoneButtonLabel",
241 l10n_util::GetStringUTF16(
242 IDS_EASY_UNLOCK_SETUP_INTRO_FINDING_PHONE_BUTTON_LABEL
));
244 "setupIntroRetryFindPhoneButtonLabel",
245 l10n_util::GetStringUTF16(
246 IDS_EASY_UNLOCK_SETUP_INTRO_RETRY_FIND_PHONE_BUTTON_LABEL
));
248 "setupIntroCloseFindPhoneButtonLabel",
249 l10n_util::GetStringUTF16(
250 IDS_EASY_UNLOCK_SETUP_INTRO_CLOSE_FIND_PHONE_BUTTON_LABEL
));
252 "setupIntroHowIsThisSecureLinkText",
253 l10n_util::GetStringUTF16(
254 IDS_EASY_UNLOCK_SETUP_INTRO_HOW_IS_THIS_SECURE_LINK_TEXT
));
255 // Step 1.5: Phone found but is not secured with lock screen
256 strings
->SetString("setupSecurePhoneHeaderTitle",
257 l10n_util::GetStringUTF16(
258 IDS_EASY_UNLOCK_SETUP_SECURE_PHONE_HEADER_TITLE
));
260 "setupSecurePhoneHeaderText",
261 l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_SECURE_PHONE_HEADER_TEXT
,
263 strings
->SetString("setupSecurePhoneButtonLabel",
264 l10n_util::GetStringUTF16(
265 IDS_EASY_UNLOCK_SETUP_SECURE_PHONE_BUTTON_LABEL
));
266 strings
->SetString("setupSecurePhoneLinkText",
267 l10n_util::GetStringUTF16(
268 IDS_EASY_UNLOCK_SETUP_SECURE_PHONE_LINK_TEXT
));
269 // Step 2: Found a viable phone.
271 "setupFoundPhoneHeaderTitle",
272 l10n_util::GetStringFUTF16(
273 IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_HEADER_TITLE
, device_type
));
275 "setupFoundPhoneHeaderText",
276 l10n_util::GetStringFUTF16(
277 IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_HEADER_TEXT
, device_type
));
279 "setupFoundPhoneUseThisPhoneButtonLabel",
280 l10n_util::GetStringUTF16(
281 IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_USE_THIS_PHONE_BUTTON_LABEL
));
282 strings
->SetString("setupFoundPhoneDeviceFormattedButtonLabel",
283 l10n_util::GetStringUTF16(
284 IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_DEVICE_FORMATTED_BUTTON_LABEL
));
286 "setupFoundPhoneSwitchPhoneLinkLabel",
287 l10n_util::GetStringUTF16(
288 IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_SWITCH_PHONE_LINK_LABEL
));
290 "setupPairingPhoneFailedButtonLabel",
291 l10n_util::GetStringUTF16(
292 IDS_EASY_UNLOCK_SETUP_PAIRING_PHONE_FAILED_BUTTON_LABEL
));
293 // Step 2.5: Recommend user to set up Android Smart Lock
295 "setupAndroidSmartLockHeaderTitle",
296 l10n_util::GetStringUTF16(
297 IDS_EASY_UNLOCK_SETUP_ANDROID_SMART_LOCK_HEADER_TITLE
));
299 "setupAndroidSmartLockHeaderText",
300 l10n_util::GetStringFUTF16(
301 IDS_EASY_UNLOCK_SETUP_ANDROID_SMART_LOCK_HEADER_TEXT
, device_type
));
303 "setupAndroidSmartLockDoneButtonText",
304 l10n_util::GetStringUTF16(
305 IDS_EASY_UNLOCK_SETUP_ANDROID_SMART_LOCK_DONE_BUTTON_LABEL
));
307 "setupAndroidSmartLockAboutLinkText",
308 l10n_util::GetStringUTF16(
309 IDS_EASY_UNLOCK_SETUP_ANDROID_SMART_LOCK_ABOUT_LINK_TEXT
));
310 // Step 3: Setup completed successfully.
312 "setupCompleteHeaderTitle",
313 l10n_util::GetStringUTF16(
314 IDS_EASY_UNLOCK_SETUP_COMPLETE_HEADER_TITLE
));
316 "setupCompleteHeaderText",
317 l10n_util::GetStringUTF16(
318 IDS_EASY_UNLOCK_SETUP_COMPLETE_HEADER_TEXT
));
320 "setupCompleteTryItOutButtonLabel",
321 l10n_util::GetStringUTF16(
322 IDS_EASY_UNLOCK_SETUP_COMPLETE_TRY_IT_OUT_BUTTON_LABEL
));
324 "setupCompleteSettingsLinkText",
325 l10n_util::GetStringUTF16(
326 IDS_EASY_UNLOCK_SETUP_COMPLETE_SETTINGS_LINK_TEXT
));
327 // Step 4: Post lockscreen confirmation.
328 strings
->SetString("setupPostLockDismissButtonLabel",
329 l10n_util::GetStringUTF16(
330 IDS_EASY_UNLOCK_SETUP_POST_LOCK_DISMISS_BUTTON_LABEL
));
334 "setupErrorBluetoothUnavailable",
335 l10n_util::GetStringFUTF16(
336 IDS_EASY_UNLOCK_SETUP_ERROR_BLUETOOTH_UNAVAILBLE
, device_type
));
339 l10n_util::GetStringFUTF16(
340 IDS_EASY_UNLOCK_SETUP_ERROR_OFFLINE
, device_type
));
342 "setupErrorRemoteSoftwareOutOfDate",
343 l10n_util::GetStringUTF16(
344 IDS_EASY_UNLOCK_SETUP_ERROR_REMOTE_SOFTWARE_OUT_OF_DATE
));
346 "setupErrorRemoteSoftwareOutOfDateGeneric",
347 l10n_util::GetStringUTF16(
348 IDS_EASY_UNLOCK_SETUP_ERROR_REMOTE_SOFTWARE_OUT_OF_DATE_GENERIC
));
350 "setupErrorFindingPhone",
351 l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SETUP_ERROR_FINDING_PHONE
));
353 "setupErrorSyncPhoneState",
354 l10n_util::GetStringUTF16(
355 IDS_EASY_UNLOCK_SETUP_ERROR_SYNC_PHONE_STATE_FAILED
));
357 "setupErrorConnectingToPhone",
358 l10n_util::GetStringFUTF16(
359 IDS_EASY_UNLOCK_SETUP_ERROR_CONNECTING_TO_PHONE
, device_type
));
361 SetResult(strings
.release());
365 EasyUnlockPrivatePerformECDHKeyAgreementFunction::
366 EasyUnlockPrivatePerformECDHKeyAgreementFunction() {}
368 EasyUnlockPrivatePerformECDHKeyAgreementFunction::
369 ~EasyUnlockPrivatePerformECDHKeyAgreementFunction() {}
371 bool EasyUnlockPrivatePerformECDHKeyAgreementFunction::RunAsync() {
372 scoped_ptr
<easy_unlock_private::PerformECDHKeyAgreement::Params
> params
=
373 easy_unlock_private::PerformECDHKeyAgreement::Params::Create(*args_
);
374 EXTENSION_FUNCTION_VALIDATE(params
);
376 GetCryptoDelegate(browser_context())->PerformECDHKeyAgreement(
378 base::Bind(&EasyUnlockPrivatePerformECDHKeyAgreementFunction::OnData
,
383 void EasyUnlockPrivatePerformECDHKeyAgreementFunction::OnData(
384 const std::string
& secret_key
) {
385 // TODO(tbarzic): Improve error handling.
386 if (!secret_key
.empty()) {
387 results_
= easy_unlock_private::PerformECDHKeyAgreement::Results::Create(
388 std::vector
<char>(secret_key
.begin(), secret_key
.end()));
393 EasyUnlockPrivateGenerateEcP256KeyPairFunction::
394 EasyUnlockPrivateGenerateEcP256KeyPairFunction() {}
396 EasyUnlockPrivateGenerateEcP256KeyPairFunction::
397 ~EasyUnlockPrivateGenerateEcP256KeyPairFunction() {}
399 bool EasyUnlockPrivateGenerateEcP256KeyPairFunction::RunAsync() {
400 GetCryptoDelegate(browser_context())->GenerateEcP256KeyPair(
401 base::Bind(&EasyUnlockPrivateGenerateEcP256KeyPairFunction::OnData
,
406 void EasyUnlockPrivateGenerateEcP256KeyPairFunction::OnData(
407 const std::string
& private_key
,
408 const std::string
& public_key
) {
409 // TODO(tbarzic): Improve error handling.
410 if (!public_key
.empty() && !private_key
.empty()) {
411 results_
= easy_unlock_private::GenerateEcP256KeyPair::Results::Create(
412 std::vector
<char>(public_key
.begin(), public_key
.end()),
413 std::vector
<char>(private_key
.begin(), private_key
.end()));
418 EasyUnlockPrivateCreateSecureMessageFunction::
419 EasyUnlockPrivateCreateSecureMessageFunction() {}
421 EasyUnlockPrivateCreateSecureMessageFunction::
422 ~EasyUnlockPrivateCreateSecureMessageFunction() {}
424 bool EasyUnlockPrivateCreateSecureMessageFunction::RunAsync() {
425 scoped_ptr
<easy_unlock_private::CreateSecureMessage::Params
> params
=
426 easy_unlock_private::CreateSecureMessage::Params::Create(*args_
);
427 EXTENSION_FUNCTION_VALIDATE(params
);
429 GetCryptoDelegate(browser_context())->CreateSecureMessage(
431 base::Bind(&EasyUnlockPrivateCreateSecureMessageFunction::OnData
,
436 void EasyUnlockPrivateCreateSecureMessageFunction::OnData(
437 const std::string
& message
) {
438 // TODO(tbarzic): Improve error handling.
439 if (!message
.empty()) {
440 results_
= easy_unlock_private::CreateSecureMessage::Results::Create(
441 std::vector
<char>(message
.begin(), message
.end()));
446 EasyUnlockPrivateUnwrapSecureMessageFunction::
447 EasyUnlockPrivateUnwrapSecureMessageFunction() {}
449 EasyUnlockPrivateUnwrapSecureMessageFunction::
450 ~EasyUnlockPrivateUnwrapSecureMessageFunction() {}
452 bool EasyUnlockPrivateUnwrapSecureMessageFunction::RunAsync() {
453 scoped_ptr
<easy_unlock_private::UnwrapSecureMessage::Params
> params
=
454 easy_unlock_private::UnwrapSecureMessage::Params::Create(*args_
);
455 EXTENSION_FUNCTION_VALIDATE(params
);
457 GetCryptoDelegate(browser_context())->UnwrapSecureMessage(
459 base::Bind(&EasyUnlockPrivateUnwrapSecureMessageFunction::OnData
,
464 void EasyUnlockPrivateUnwrapSecureMessageFunction::OnData(
465 const std::string
& data
) {
466 // TODO(tbarzic): Improve error handling.
468 results_
= easy_unlock_private::UnwrapSecureMessage::Results::Create(
469 std::vector
<char>(data
.begin(), data
.end()));
474 EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::
475 EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction() {}
477 EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::
478 ~EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction() {}
480 bool EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::RunAsync() {
481 scoped_ptr
<easy_unlock_private::SeekBluetoothDeviceByAddress::Params
> params(
482 easy_unlock_private::SeekBluetoothDeviceByAddress::Params::Create(
484 EXTENSION_FUNCTION_VALIDATE(params
.get());
486 proximity_auth::bluetooth_util::SeekDeviceByAddress(
487 params
->device_address
,
489 &EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekSuccess
,
492 &EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekFailure
,
494 content::BrowserThread::GetBlockingPool()
495 ->GetTaskRunnerWithShutdownBehavior(
496 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
)
501 void EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekSuccess() {
505 void EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekFailure(
506 const std::string
& error_message
) {
507 SetError(error_message
);
511 EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
512 EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
514 EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
515 ~EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
517 void EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
518 ConnectToService(device::BluetoothDevice
* device
,
519 const device::BluetoothUUID
& uuid
) {
520 device
->ConnectToServiceInsecurely(
522 base::Bind(&EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
525 base::Bind(&EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
530 EasyUnlockPrivateUpdateScreenlockStateFunction::
531 EasyUnlockPrivateUpdateScreenlockStateFunction() {}
533 EasyUnlockPrivateUpdateScreenlockStateFunction::
534 ~EasyUnlockPrivateUpdateScreenlockStateFunction() {}
536 bool EasyUnlockPrivateUpdateScreenlockStateFunction::RunSync() {
537 scoped_ptr
<easy_unlock_private::UpdateScreenlockState::Params
> params(
538 easy_unlock_private::UpdateScreenlockState::Params::Create(*args_
));
539 EXTENSION_FUNCTION_VALIDATE(params
.get());
541 Profile
* profile
= Profile::FromBrowserContext(browser_context());
542 if (EasyUnlockService::Get(profile
)->UpdateScreenlockState(
543 ToScreenlockState(params
->state
)))
546 SetError("Not allowed");
550 EasyUnlockPrivateSetPermitAccessFunction::
551 EasyUnlockPrivateSetPermitAccessFunction() {
554 EasyUnlockPrivateSetPermitAccessFunction::
555 ~EasyUnlockPrivateSetPermitAccessFunction() {
558 bool EasyUnlockPrivateSetPermitAccessFunction::RunSync() {
559 scoped_ptr
<easy_unlock_private::SetPermitAccess::Params
> params(
560 easy_unlock_private::SetPermitAccess::Params::Create(*args_
));
561 EXTENSION_FUNCTION_VALIDATE(params
.get());
563 Profile
* profile
= Profile::FromBrowserContext(browser_context());
564 EasyUnlockService::Get(profile
)
565 ->SetPermitAccess(*params
->permit_access
.ToValue());
570 EasyUnlockPrivateGetPermitAccessFunction::
571 EasyUnlockPrivateGetPermitAccessFunction() {
574 EasyUnlockPrivateGetPermitAccessFunction::
575 ~EasyUnlockPrivateGetPermitAccessFunction() {
578 bool EasyUnlockPrivateGetPermitAccessFunction::RunSync() {
579 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
580 proximity_auth::switches::kEnableBluetoothLowEnergyDiscovery
)) {
581 ReturnPermitAccessForExperiment();
585 Profile
* profile
= Profile::FromBrowserContext(browser_context());
586 const base::DictionaryValue
* permit_value
=
587 EasyUnlockService::Get(profile
)->GetPermitAccess();
589 scoped_ptr
<easy_unlock_private::PermitRecord
> permit
=
590 easy_unlock_private::PermitRecord::FromValue(*permit_value
);
591 results_
= easy_unlock_private::GetPermitAccess::Results::Create(*permit
);
597 void EasyUnlockPrivateGetPermitAccessFunction::GetKeyPairForExperiment(
598 std::string
* user_public_key
,
599 std::string
* user_private_key
) {
600 Profile
* profile
= Profile::FromBrowserContext(browser_context());
601 proximity_auth::CryptAuthEnrollmentManager
* enrollment_manager
=
602 EasyUnlockService::Get(profile
)
603 ->proximity_auth_client()
604 ->GetCryptAuthEnrollmentManager();
605 proximity_auth::Base64UrlEncode(enrollment_manager
->GetUserPublicKey(),
607 proximity_auth::Base64UrlEncode(enrollment_manager
->GetUserPrivateKey(),
611 void EasyUnlockPrivateGetPermitAccessFunction::
612 ReturnPermitAccessForExperiment() {
613 // Check that we are inside a user session.
614 Profile
* profile
= Profile::FromBrowserContext(browser_context());
615 EasyUnlockService
* easy_unlock_service
= EasyUnlockService::Get(profile
);
616 if (easy_unlock_service
->GetType() != EasyUnlockService::TYPE_REGULAR
) {
617 SetError("This function must be called inside a user session.");
622 std::string b64_public_key
, b64_private_key
;
623 GetKeyPairForExperiment(&b64_public_key
, &b64_private_key
);
625 // Fill in the permit access JSON dictionary.
626 proximity_auth::ProximityAuthClient
* client
=
627 easy_unlock_service
->proximity_auth_client();
628 scoped_ptr
<base::DictionaryValue
> permit_access(new base::DictionaryValue());
629 permit_access
->SetString("permitId",
630 "permit://google.com/" + client
->GetAccountId());
631 permit_access
->SetString("id", b64_public_key
);
632 permit_access
->SetString("type", "access");
633 permit_access
->SetString("data", b64_private_key
);
635 PA_LOG(INFO
) << "Returning permit access for "
636 << "chrome.easyUnlockPrivate.getPermitAccess:\n"
637 << " id: " << b64_public_key
;
639 scoped_ptr
<easy_unlock_private::PermitRecord
> result
=
640 easy_unlock_private::PermitRecord::FromValue(*permit_access
);
641 results_
= easy_unlock_private::GetPermitAccess::Results::Create(*result
);
644 EasyUnlockPrivateClearPermitAccessFunction::
645 EasyUnlockPrivateClearPermitAccessFunction() {
648 EasyUnlockPrivateClearPermitAccessFunction::
649 ~EasyUnlockPrivateClearPermitAccessFunction() {
652 bool EasyUnlockPrivateClearPermitAccessFunction::RunSync() {
653 Profile
* profile
= Profile::FromBrowserContext(browser_context());
654 EasyUnlockService::Get(profile
)->ClearPermitAccess();
658 EasyUnlockPrivateSetRemoteDevicesFunction::
659 EasyUnlockPrivateSetRemoteDevicesFunction() {
662 EasyUnlockPrivateSetRemoteDevicesFunction::
663 ~EasyUnlockPrivateSetRemoteDevicesFunction() {
666 bool EasyUnlockPrivateSetRemoteDevicesFunction::RunSync() {
667 scoped_ptr
<easy_unlock_private::SetRemoteDevices::Params
> params(
668 easy_unlock_private::SetRemoteDevices::Params::Create(*args_
));
669 EXTENSION_FUNCTION_VALIDATE(params
.get());
671 Profile
* profile
= Profile::FromBrowserContext(browser_context());
672 base::ListValue devices
;
673 for (size_t i
= 0; i
< params
->devices
.size(); ++i
) {
674 devices
.Append(params
->devices
[i
]->ToValue().release());
676 EasyUnlockService::Get(profile
)->SetRemoteDevices(devices
);
681 EasyUnlockPrivateGetRemoteDevicesFunction::
682 EasyUnlockPrivateGetRemoteDevicesFunction() {
685 EasyUnlockPrivateGetRemoteDevicesFunction::
686 ~EasyUnlockPrivateGetRemoteDevicesFunction() {
689 bool EasyUnlockPrivateGetRemoteDevicesFunction::RunAsync() {
690 // Return the remote devices stored with the native CryptAuthDeviceManager if
691 // we are trying out the BLE experiment.
692 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
693 proximity_auth::switches::kEnableBluetoothLowEnergyDiscovery
)) {
694 ReturnDevicesForExperiment();
696 Profile
* profile
= Profile::FromBrowserContext(browser_context());
697 const base::ListValue
* devices
=
698 EasyUnlockService::Get(profile
)->GetRemoteDevices();
699 SetResult(devices
? devices
->DeepCopy() : new base::ListValue());
706 std::string
EasyUnlockPrivateGetRemoteDevicesFunction::GetUserPrivateKey() {
707 Profile
* profile
= Profile::FromBrowserContext(browser_context());
708 proximity_auth::ProximityAuthClient
* client
=
709 EasyUnlockService::Get(profile
)->proximity_auth_client();
710 proximity_auth::CryptAuthEnrollmentManager
* enrollment_manager
=
711 client
->GetCryptAuthEnrollmentManager();
712 return enrollment_manager
->GetUserPrivateKey();
715 std::vector
<cryptauth::ExternalDeviceInfo
>
716 EasyUnlockPrivateGetRemoteDevicesFunction::GetUnlockKeys() {
717 Profile
* profile
= Profile::FromBrowserContext(browser_context());
718 proximity_auth::ProximityAuthClient
* client
=
719 EasyUnlockService::Get(profile
)->proximity_auth_client();
720 proximity_auth::CryptAuthDeviceManager
* device_manager
=
721 client
->GetCryptAuthDeviceManager();
722 return device_manager
->unlock_keys();
725 void EasyUnlockPrivateGetRemoteDevicesFunction::ReturnDevicesForExperiment() {
726 // Check that we are inside a user profile.
727 Profile
* profile
= Profile::FromBrowserContext(browser_context());
728 EasyUnlockService
* easy_unlock_service
= EasyUnlockService::Get(profile
);
729 if (easy_unlock_service
->GetType() != EasyUnlockService::TYPE_REGULAR
) {
730 SetError("This function must be called inside a user session.");
735 // Get the synced unlock key data.
736 proximity_auth::ProximityAuthClient
* client
=
737 easy_unlock_service
->proximity_auth_client();
739 permit_id_
= "permit://google.com/easyunlock/v1/" + client
->GetAccountId();
740 secure_message_delegate_
= client
->CreateSecureMessageDelegate();
741 std::vector
<cryptauth::ExternalDeviceInfo
> unlock_keys
= GetUnlockKeys();
742 expected_devices_count_
= unlock_keys
.size();
744 remote_devices_
.reset(new base::ListValue());
745 if (expected_devices_count_
== 0) {
746 SetResult(remote_devices_
.Pass());
751 // If there is a BLE unlock key, then don't return anything, so the app does
752 // not try the classic Bluetooth protocol.
753 for (const auto& unlock_key
: unlock_keys
) {
754 if (unlock_key
.bluetooth_address().empty()) {
755 SetResult(remote_devices_
.Pass());
761 // Derive the PSKs for the user's unlock keys.
762 PA_LOG(INFO
) << "Deriving PSKs for "
763 << "chrome.easyUnlockPrivate.getRemoteDevices.\n"
764 << "Expecting " << expected_devices_count_
<< " devices.";
765 for (const auto& unlock_key
: unlock_keys
) {
766 secure_message_delegate_
->DeriveKey(
767 GetUserPrivateKey(), unlock_key
.public_key(),
769 &EasyUnlockPrivateGetRemoteDevicesFunction::OnPSKDerivedForDevice
,
774 void EasyUnlockPrivateGetRemoteDevicesFunction::OnPSKDerivedForDevice(
775 const cryptauth::ExternalDeviceInfo
& device
,
776 const std::string
& persistent_symmetric_key
) {
777 std::string b64_public_key
, b64_psk
;
778 proximity_auth::Base64UrlEncode(device
.public_key(), &b64_public_key
);
779 proximity_auth::Base64UrlEncode(persistent_symmetric_key
, &b64_psk
);
781 // Fill in the JSON dictionary containing a single unlock key's data.
782 scoped_ptr
<base::DictionaryValue
> device_dictionary(
783 new base::DictionaryValue());
784 device_dictionary
->SetString("name", device
.friendly_device_name());
785 device_dictionary
->SetString("bluetoothAddress", device
.bluetooth_address());
786 device_dictionary
->SetString("psk", b64_psk
);
788 // Fill in the permit license for the unlock key.
789 scoped_ptr
<base::DictionaryValue
> permit_license(new base::DictionaryValue());
790 permit_license
->SetString("permitId", permit_id_
);
791 permit_license
->SetString("id", b64_public_key
);
792 permit_license
->SetString("type", "license");
793 permit_license
->SetString("data", b64_public_key
);
794 device_dictionary
->Set("permitRecord", permit_license
.Pass());
796 remote_devices_
->Append(device_dictionary
.Pass());
798 // If all PSKs are derived, then return from the API call.
799 PA_LOG(INFO
) << "Derived PSK for " << b64_public_key
<< ": "
800 << remote_devices_
->GetSize() << "/" << expected_devices_count_
;
801 if (remote_devices_
->GetSize() == expected_devices_count_
) {
802 SetResult(remote_devices_
.Pass());
807 EasyUnlockPrivateGetSignInChallengeFunction::
808 EasyUnlockPrivateGetSignInChallengeFunction() {
811 EasyUnlockPrivateGetSignInChallengeFunction::
812 ~EasyUnlockPrivateGetSignInChallengeFunction() {
815 bool EasyUnlockPrivateGetSignInChallengeFunction::RunAsync() {
816 scoped_ptr
<easy_unlock_private::GetSignInChallenge::Params
> params(
817 easy_unlock_private::GetSignInChallenge::Params::Create(*args_
));
818 EXTENSION_FUNCTION_VALIDATE(params
.get());
820 #if defined(OS_CHROMEOS)
821 Profile
* profile
= Profile::FromBrowserContext(browser_context());
822 const std::string challenge
=
823 EasyUnlockService::Get(profile
)->GetChallenge();
824 if (!challenge
.empty() && !params
->nonce
.empty()) {
825 EasyUnlockTpmKeyManager
* key_manager
=
826 EasyUnlockTpmKeyManagerFactory::GetInstance()->Get(profile
);
828 SetError("No EasyUnlockTpmKeyManager.");
831 key_manager
->SignUsingTpmKey(
832 EasyUnlockService::Get(profile
)->GetUserEmail(),
833 std::string(params
->nonce
.begin(), params
->nonce
.end()),
834 base::Bind(&EasyUnlockPrivateGetSignInChallengeFunction::OnDone
, this,
837 OnDone(challenge
, std::string());
840 #else // if !defined(OS_CHROMEOS)
841 SetError("Sign-in not supported.");
843 #endif // defined(OS_CHROMEOS)
846 void EasyUnlockPrivateGetSignInChallengeFunction::OnDone(
847 const std::string
& challenge
,
848 const std::string
& signed_nonce
) {
849 results_
= easy_unlock_private::GetSignInChallenge::Results::Create(
850 std::vector
<char>(challenge
.begin(), challenge
.end()),
851 std::vector
<char>(signed_nonce
.begin(), signed_nonce
.end()));
855 EasyUnlockPrivateTrySignInSecretFunction::
856 EasyUnlockPrivateTrySignInSecretFunction() {
859 EasyUnlockPrivateTrySignInSecretFunction::
860 ~EasyUnlockPrivateTrySignInSecretFunction() {
863 bool EasyUnlockPrivateTrySignInSecretFunction::RunSync() {
864 scoped_ptr
<easy_unlock_private::TrySignInSecret::Params
> params(
865 easy_unlock_private::TrySignInSecret::Params::Create(*args_
));
866 EXTENSION_FUNCTION_VALIDATE(params
.get());
868 Profile
* profile
= Profile::FromBrowserContext(browser_context());
869 EasyUnlockService::Get(profile
)->FinalizeSignin(std::string(
870 params
->sign_in_secret
.begin(), params
->sign_in_secret
.end()));
874 EasyUnlockPrivateGetUserInfoFunction::EasyUnlockPrivateGetUserInfoFunction() {
877 EasyUnlockPrivateGetUserInfoFunction::~EasyUnlockPrivateGetUserInfoFunction() {
880 bool EasyUnlockPrivateGetUserInfoFunction::RunSync() {
881 EasyUnlockService
* service
=
882 EasyUnlockService::Get(Profile::FromBrowserContext(browser_context()));
883 std::vector
<linked_ptr
<easy_unlock_private::UserInfo
> > users
;
884 std::string user_id
= service
->GetUserEmail();
885 if (!user_id
.empty()) {
887 linked_ptr
<easy_unlock_private::UserInfo
>(
888 new easy_unlock_private::UserInfo()));
889 users
[0]->user_id
= user_id
;
890 users
[0]->logged_in
= service
->GetType() == EasyUnlockService::TYPE_REGULAR
;
891 users
[0]->data_ready
= users
[0]->logged_in
||
892 service
->GetRemoteDevices() != NULL
;
894 EasyUnlockService::UserSettings user_settings
=
895 EasyUnlockService::GetUserSettings(user_id
);
896 users
[0]->require_close_proximity
= user_settings
.require_close_proximity
;
898 users
[0]->device_user_id
= proximity_auth::CalculateDeviceUserId(
899 EasyUnlockService::GetDeviceId(), user_id
);
901 users
[0]->ble_discovery_enabled
=
902 base::CommandLine::ForCurrentProcess()->HasSwitch(
903 proximity_auth::switches::kEnableBluetoothLowEnergyDiscovery
);
905 results_
= easy_unlock_private::GetUserInfo::Results::Create(users
);
909 EasyUnlockPrivateGetConnectionInfoFunction::
910 EasyUnlockPrivateGetConnectionInfoFunction() {
913 EasyUnlockPrivateGetConnectionInfoFunction::
914 ~EasyUnlockPrivateGetConnectionInfoFunction() {
917 bool EasyUnlockPrivateGetConnectionInfoFunction::DoWork(
918 scoped_refptr
<device::BluetoothAdapter
> adapter
) {
919 scoped_ptr
<easy_unlock_private::GetConnectionInfo::Params
> params
=
920 easy_unlock_private::GetConnectionInfo::Params::Create(*args_
);
921 EXTENSION_FUNCTION_VALIDATE(params
);
923 device::BluetoothDevice
* device
= adapter
->GetDevice(params
->device_address
);
927 error
= "Invalid Bluetooth device.";
928 else if (!device
->IsConnected())
929 error
= "Bluetooth device not connected.";
931 if (!error
.empty()) {
937 device
->GetConnectionInfo(base::Bind(
938 &EasyUnlockPrivateGetConnectionInfoFunction::OnConnectionInfo
, this));
942 void EasyUnlockPrivateGetConnectionInfoFunction::OnConnectionInfo(
943 const device::BluetoothDevice::ConnectionInfo
& connection_info
) {
944 scoped_ptr
<base::ListValue
> results(new base::ListValue());
945 results
->AppendInteger(connection_info
.rssi
);
946 results
->AppendInteger(connection_info
.transmit_power
);
947 results
->AppendInteger(connection_info
.max_transmit_power
);
948 SetResultList(results
.Pass());
952 EasyUnlockPrivateShowErrorBubbleFunction::
953 EasyUnlockPrivateShowErrorBubbleFunction() {
956 EasyUnlockPrivateShowErrorBubbleFunction::
957 ~EasyUnlockPrivateShowErrorBubbleFunction() {
960 bool EasyUnlockPrivateShowErrorBubbleFunction::RunSync() {
961 content::WebContents
* web_contents
= GetAssociatedWebContents();
963 SetError("A foreground app window is required.");
967 scoped_ptr
<easy_unlock_private::ShowErrorBubble::Params
> params(
968 easy_unlock_private::ShowErrorBubble::Params::Create(*args_
));
969 EXTENSION_FUNCTION_VALIDATE(params
.get());
971 if (params
->link_range
.start
< 0 ||
972 params
->link_range
.end
< 0 ||
973 base::saturated_cast
<size_t>(params
->link_range
.end
) >
974 params
->message
.size()) {
975 SetError("Invalid link range.");
979 #if defined(TOOLKIT_VIEWS)
980 gfx::Rect
anchor_rect(
981 params
->anchor_rect
.left
, params
->anchor_rect
.top
,
982 params
->anchor_rect
.width
, params
->anchor_rect
.height
);
984 web_contents
->GetContainerBounds().OffsetFromOrigin();
985 ShowProximityAuthErrorBubble(
986 base::UTF8ToUTF16(params
->message
),
987 gfx::Range(params
->link_range
.start
, params
->link_range
.end
),
988 GURL(params
->link_target
), anchor_rect
, web_contents
);
990 SetError("Not supported on non-Views platforms.");
995 EasyUnlockPrivateHideErrorBubbleFunction::
996 EasyUnlockPrivateHideErrorBubbleFunction() {
999 EasyUnlockPrivateHideErrorBubbleFunction::
1000 ~EasyUnlockPrivateHideErrorBubbleFunction() {
1003 bool EasyUnlockPrivateHideErrorBubbleFunction::RunSync() {
1004 #if defined(TOOLKIT_VIEWS)
1005 HideProximityAuthErrorBubble();
1007 SetError("Not supported on non-Views platforms.");
1012 EasyUnlockPrivateSetAutoPairingResultFunction::
1013 EasyUnlockPrivateSetAutoPairingResultFunction() {
1016 EasyUnlockPrivateSetAutoPairingResultFunction::
1017 ~EasyUnlockPrivateSetAutoPairingResultFunction() {
1020 bool EasyUnlockPrivateSetAutoPairingResultFunction::RunSync() {
1021 scoped_ptr
<easy_unlock_private::SetAutoPairingResult::Params
> params
=
1022 easy_unlock_private::SetAutoPairingResult::Params::Create(*args_
);
1023 EXTENSION_FUNCTION_VALIDATE(params
);
1025 std::string error_message
;
1026 if (params
->result
.error_message
)
1027 error_message
= *params
->result
.error_message
;
1029 Profile
* profile
= Profile::FromBrowserContext(browser_context());
1030 EasyUnlockService::Get(profile
)
1031 ->SetAutoPairingResult(params
->result
.success
, error_message
);
1036 EasyUnlockPrivateFindSetupConnectionFunction::
1037 EasyUnlockPrivateFindSetupConnectionFunction()
1038 : bluetooth_throttler_(new proximity_auth::BluetoothThrottlerImpl(
1039 make_scoped_ptr(new base::DefaultTickClock()))) {}
1041 EasyUnlockPrivateFindSetupConnectionFunction::
1042 ~EasyUnlockPrivateFindSetupConnectionFunction() {}
1044 void EasyUnlockPrivateFindSetupConnectionFunction::
1045 OnConnectionFinderTimedOut() {
1046 SetError("No connection found.");
1047 connection_finder_
.reset();
1048 SendResponse(false);
1051 void EasyUnlockPrivateFindSetupConnectionFunction::OnConnectionFound(
1052 scoped_ptr
<proximity_auth::Connection
> connection
) {
1053 // Connection are not persistent by default.
1054 std::string device_address
= connection
->remote_device().bluetooth_address
;
1055 bool persistent
= false;
1057 GetConnectionManager(browser_context())
1058 ->AddConnection(extension(), connection
.Pass(), persistent
);
1059 results_
= easy_unlock_private::FindSetupConnection::Results::Create(
1060 connection_id
, device_address
);
1064 bool EasyUnlockPrivateFindSetupConnectionFunction::RunAsync() {
1065 scoped_ptr
<easy_unlock_private::FindSetupConnection::Params
> params
=
1066 easy_unlock_private::FindSetupConnection::Params::Create(*args_
);
1067 EXTENSION_FUNCTION_VALIDATE(params
);
1069 // Creates a BLE connection finder to look for any device advertising
1070 // |params->setup_service_uuid|.
1071 connection_finder_
.reset(
1072 new proximity_auth::BluetoothLowEnergyConnectionFinder(
1073 proximity_auth::RemoteDevice(), params
->setup_service_uuid
,
1074 proximity_auth::BluetoothLowEnergyConnectionFinder::FIND_ANY_DEVICE
,
1075 nullptr, bluetooth_throttler_
.get(), 3));
1077 connection_finder_
->Find(base::Bind(
1078 &EasyUnlockPrivateFindSetupConnectionFunction::OnConnectionFound
, this));
1081 new base::OneShotTimer
<EasyUnlockPrivateFindSetupConnectionFunction
>());
1082 timer_
->Start(FROM_HERE
, base::TimeDelta::FromSeconds(params
->time_out
),
1083 base::Bind(&EasyUnlockPrivateFindSetupConnectionFunction::
1084 OnConnectionFinderTimedOut
,
1090 EasyUnlockPrivateSetupConnectionStatusFunction::
1091 EasyUnlockPrivateSetupConnectionStatusFunction() {}
1093 EasyUnlockPrivateSetupConnectionStatusFunction::
1094 ~EasyUnlockPrivateSetupConnectionStatusFunction() {}
1096 bool EasyUnlockPrivateSetupConnectionStatusFunction::RunSync() {
1097 scoped_ptr
<easy_unlock_private::SetupConnectionStatus::Params
> params
=
1098 easy_unlock_private::SetupConnectionStatus::Params::Create(*args_
);
1099 EXTENSION_FUNCTION_VALIDATE(params
);
1100 api::easy_unlock_private::ConnectionStatus status
=
1101 GetConnectionManager(browser_context())
1102 ->ConnectionStatus(extension(), params
->connection_id
);
1104 easy_unlock_private::SetupConnectionStatus::Results::Create(status
);
1105 if (status
== api::easy_unlock_private::CONNECTION_STATUS_NONE
)
1106 SetError("Invalid connectionId");
1110 EasyUnlockPrivateSetupConnectionDisconnectFunction::
1111 EasyUnlockPrivateSetupConnectionDisconnectFunction() {}
1113 EasyUnlockPrivateSetupConnectionDisconnectFunction::
1114 ~EasyUnlockPrivateSetupConnectionDisconnectFunction() {}
1116 bool EasyUnlockPrivateSetupConnectionDisconnectFunction::RunSync() {
1117 scoped_ptr
<easy_unlock_private::SetupConnectionDisconnect::Params
> params
=
1118 easy_unlock_private::SetupConnectionDisconnect::Params::Create(*args_
);
1119 EXTENSION_FUNCTION_VALIDATE(params
);
1120 bool success
= GetConnectionManager(browser_context())
1121 ->Disconnect(extension(), params
->connection_id
);
1123 SetError("Invalid connectionId.");
1127 EasyUnlockPrivateSetupConnectionSendFunction::
1128 EasyUnlockPrivateSetupConnectionSendFunction() {}
1130 EasyUnlockPrivateSetupConnectionSendFunction::
1131 ~EasyUnlockPrivateSetupConnectionSendFunction() {}
1133 bool EasyUnlockPrivateSetupConnectionSendFunction::RunSync() {
1134 scoped_ptr
<easy_unlock_private::SetupConnectionSend::Params
> params
=
1135 easy_unlock_private::SetupConnectionSend::Params::Create(*args_
);
1136 EXTENSION_FUNCTION_VALIDATE(params
);
1137 std::string
payload(params
->data
.begin(), params
->data
.end());
1138 bool success
= GetConnectionManager(browser_context())
1139 ->SendMessage(extension(), params
->connection_id
, payload
);
1141 SetError("Invalid connectionId.");
1145 } // namespace extensions