Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / easy_unlock_private / easy_unlock_private_api.cc
blob6fde8c42101b32a6598bb70b81e3407ad0c19719
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"
7 #include <vector>
9 #include "base/bind.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"
58 #endif
60 using proximity_auth::ScreenlockState;
62 namespace extensions {
64 namespace easy_unlock_private = api::easy_unlock_private;
66 namespace {
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) {
85 switch (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;
108 default:
109 return ScreenlockState::INACTIVE;
113 } // namespace
115 // static
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();
142 #else
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);
153 #else
154 // TODO(isherman): Set an appropriate user display email for non-ChromeOS
155 // platforms.
156 const base::string16 user_email = base::UTF8ToUTF16("superman@example.com");
157 #endif // defined(OS_CHROMEOS)
159 // Common strings.
160 strings->SetString(
161 "learnMoreLinkTitle",
162 l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_LEARN_MORE_LINK_TITLE));
163 strings->SetString("deviceType", device_type);
165 // Setup notification strings.
166 strings->SetString(
167 "setupNotificationTitle",
168 l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SETUP_NOTIFICATION_TITLE));
169 strings->SetString(
170 "setupNotificationMessage",
171 l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_NOTIFICATION_MESSAGE,
172 device_type));
173 strings->SetString(
174 "setupNotificationButtonTitle",
175 l10n_util::GetStringUTF16(
176 IDS_EASY_UNLOCK_SETUP_NOTIFICATION_BUTTON_TITLE));
178 // Chromebook added to Easy Unlock notification strings.
179 strings->SetString(
180 "chromebookAddedNotificationTitle",
181 l10n_util::GetStringUTF16(
182 IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_TITLE));
183 strings->SetString(
184 "chromebookAddedNotificationMessage",
185 l10n_util::GetStringFUTF16(
186 IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_MESSAGE,
187 device_type));
188 strings->SetString(
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.
195 strings->SetString(
196 "phoneChangedNotificationLearnMoreButton",
197 l10n_util::GetStringUTF16(
198 IDS_EASY_UNLOCK_NOTIFICATION_LEARN_MORE_BUTTON));
200 // Pairing changed notification strings.
201 strings->SetString(
202 "phoneChangedNotificationTitle",
203 l10n_util::GetStringUTF16(
204 IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_TITLE));
205 strings->SetString(
206 "phoneChangedNotificationMessage",
207 l10n_util::GetStringFUTF16(
208 IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_MESSAGE,
209 device_type));
210 strings->SetString(
211 "phoneChangedNotificationUpdateButton",
212 l10n_util::GetStringUTF16(
213 IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_UPDATE_BUTTON));
215 // Phone change applied notification strings.
216 strings->SetString(
217 "phoneChangeAppliedNotificationTitle",
218 l10n_util::GetStringUTF16(
219 IDS_EASY_UNLOCK_PAIRING_CHANGE_APPLIED_NOTIFICATION_TITLE));
220 strings->SetString(
221 "phoneChangeAppliedNotificationMessage",
222 l10n_util::GetStringUTF16(
223 IDS_EASY_UNLOCK_PAIRING_CHANGE_APPLIED_NOTIFICATION_MESSAGE));
225 // Setup dialog strings.
226 // Step 1: Intro.
227 strings->SetString(
228 "setupIntroHeaderTitle",
229 l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SETUP_INTRO_HEADER_TITLE));
230 strings->SetString(
231 "setupIntroHeaderText",
232 l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_INTRO_HEADER_TEXT,
233 device_type,
234 user_email));
235 strings->SetString(
236 "setupIntroFindPhoneButtonLabel",
237 l10n_util::GetStringUTF16(
238 IDS_EASY_UNLOCK_SETUP_INTRO_FIND_PHONE_BUTTON_LABEL));
239 strings->SetString(
240 "setupIntroFindingPhoneButtonLabel",
241 l10n_util::GetStringUTF16(
242 IDS_EASY_UNLOCK_SETUP_INTRO_FINDING_PHONE_BUTTON_LABEL));
243 strings->SetString(
244 "setupIntroRetryFindPhoneButtonLabel",
245 l10n_util::GetStringUTF16(
246 IDS_EASY_UNLOCK_SETUP_INTRO_RETRY_FIND_PHONE_BUTTON_LABEL));
247 strings->SetString(
248 "setupIntroCloseFindPhoneButtonLabel",
249 l10n_util::GetStringUTF16(
250 IDS_EASY_UNLOCK_SETUP_INTRO_CLOSE_FIND_PHONE_BUTTON_LABEL));
251 strings->SetString(
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));
259 strings->SetString(
260 "setupSecurePhoneHeaderText",
261 l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_SECURE_PHONE_HEADER_TEXT,
262 device_type));
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.
270 strings->SetString(
271 "setupFoundPhoneHeaderTitle",
272 l10n_util::GetStringFUTF16(
273 IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_HEADER_TITLE, device_type));
274 strings->SetString(
275 "setupFoundPhoneHeaderText",
276 l10n_util::GetStringFUTF16(
277 IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_HEADER_TEXT, device_type));
278 strings->SetString(
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));
285 strings->SetString(
286 "setupFoundPhoneSwitchPhoneLinkLabel",
287 l10n_util::GetStringUTF16(
288 IDS_EASY_UNLOCK_SETUP_FOUND_PHONE_SWITCH_PHONE_LINK_LABEL));
289 strings->SetString(
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
294 strings->SetString(
295 "setupAndroidSmartLockHeaderTitle",
296 l10n_util::GetStringUTF16(
297 IDS_EASY_UNLOCK_SETUP_ANDROID_SMART_LOCK_HEADER_TITLE));
298 strings->SetString(
299 "setupAndroidSmartLockHeaderText",
300 l10n_util::GetStringFUTF16(
301 IDS_EASY_UNLOCK_SETUP_ANDROID_SMART_LOCK_HEADER_TEXT, device_type));
302 strings->SetString(
303 "setupAndroidSmartLockDoneButtonText",
304 l10n_util::GetStringUTF16(
305 IDS_EASY_UNLOCK_SETUP_ANDROID_SMART_LOCK_DONE_BUTTON_LABEL));
306 strings->SetString(
307 "setupAndroidSmartLockAboutLinkText",
308 l10n_util::GetStringUTF16(
309 IDS_EASY_UNLOCK_SETUP_ANDROID_SMART_LOCK_ABOUT_LINK_TEXT));
310 // Step 3: Setup completed successfully.
311 strings->SetString(
312 "setupCompleteHeaderTitle",
313 l10n_util::GetStringUTF16(
314 IDS_EASY_UNLOCK_SETUP_COMPLETE_HEADER_TITLE));
315 strings->SetString(
316 "setupCompleteHeaderText",
317 l10n_util::GetStringUTF16(
318 IDS_EASY_UNLOCK_SETUP_COMPLETE_HEADER_TEXT));
319 strings->SetString(
320 "setupCompleteTryItOutButtonLabel",
321 l10n_util::GetStringUTF16(
322 IDS_EASY_UNLOCK_SETUP_COMPLETE_TRY_IT_OUT_BUTTON_LABEL));
323 strings->SetString(
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));
332 // Error strings.
333 strings->SetString(
334 "setupErrorBluetoothUnavailable",
335 l10n_util::GetStringFUTF16(
336 IDS_EASY_UNLOCK_SETUP_ERROR_BLUETOOTH_UNAVAILBLE, device_type));
337 strings->SetString(
338 "setupErrorOffline",
339 l10n_util::GetStringFUTF16(
340 IDS_EASY_UNLOCK_SETUP_ERROR_OFFLINE, device_type));
341 strings->SetString(
342 "setupErrorRemoteSoftwareOutOfDate",
343 l10n_util::GetStringUTF16(
344 IDS_EASY_UNLOCK_SETUP_ERROR_REMOTE_SOFTWARE_OUT_OF_DATE));
345 strings->SetString(
346 "setupErrorRemoteSoftwareOutOfDateGeneric",
347 l10n_util::GetStringUTF16(
348 IDS_EASY_UNLOCK_SETUP_ERROR_REMOTE_SOFTWARE_OUT_OF_DATE_GENERIC));
349 strings->SetString(
350 "setupErrorFindingPhone",
351 l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SETUP_ERROR_FINDING_PHONE));
352 strings->SetString(
353 "setupErrorSyncPhoneState",
354 l10n_util::GetStringUTF16(
355 IDS_EASY_UNLOCK_SETUP_ERROR_SYNC_PHONE_STATE_FAILED));
356 strings->SetString(
357 "setupErrorConnectingToPhone",
358 l10n_util::GetStringFUTF16(
359 IDS_EASY_UNLOCK_SETUP_ERROR_CONNECTING_TO_PHONE, device_type));
361 SetResult(strings.release());
362 return true;
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(
377 *params,
378 base::Bind(&EasyUnlockPrivatePerformECDHKeyAgreementFunction::OnData,
379 this));
380 return true;
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()));
390 SendResponse(true);
393 EasyUnlockPrivateGenerateEcP256KeyPairFunction::
394 EasyUnlockPrivateGenerateEcP256KeyPairFunction() {}
396 EasyUnlockPrivateGenerateEcP256KeyPairFunction::
397 ~EasyUnlockPrivateGenerateEcP256KeyPairFunction() {}
399 bool EasyUnlockPrivateGenerateEcP256KeyPairFunction::RunAsync() {
400 GetCryptoDelegate(browser_context())->GenerateEcP256KeyPair(
401 base::Bind(&EasyUnlockPrivateGenerateEcP256KeyPairFunction::OnData,
402 this));
403 return true;
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()));
415 SendResponse(true);
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(
430 *params,
431 base::Bind(&EasyUnlockPrivateCreateSecureMessageFunction::OnData,
432 this));
433 return true;
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()));
443 SendResponse(true);
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(
458 *params,
459 base::Bind(&EasyUnlockPrivateUnwrapSecureMessageFunction::OnData,
460 this));
461 return true;
464 void EasyUnlockPrivateUnwrapSecureMessageFunction::OnData(
465 const std::string& data) {
466 // TODO(tbarzic): Improve error handling.
467 if (!data.empty()) {
468 results_ = easy_unlock_private::UnwrapSecureMessage::Results::Create(
469 std::vector<char>(data.begin(), data.end()));
471 SendResponse(true);
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(
483 *args_));
484 EXTENSION_FUNCTION_VALIDATE(params.get());
486 proximity_auth::bluetooth_util::SeekDeviceByAddress(
487 params->device_address,
488 base::Bind(
489 &EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekSuccess,
490 this),
491 base::Bind(
492 &EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekFailure,
493 this),
494 content::BrowserThread::GetBlockingPool()
495 ->GetTaskRunnerWithShutdownBehavior(
496 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
497 .get());
498 return true;
501 void EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekSuccess() {
502 SendResponse(true);
505 void EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekFailure(
506 const std::string& error_message) {
507 SetError(error_message);
508 SendResponse(false);
511 EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
512 EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
514 EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
515 ~EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
517 void EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
518 ConnectToService(device::BluetoothDevice* device,
519 const device::BluetoothUUID& uuid) {
520 device->ConnectToServiceInsecurely(
521 uuid,
522 base::Bind(&EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
523 OnConnect,
524 this),
525 base::Bind(&EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
526 OnConnectError,
527 this));
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)))
544 return true;
546 SetError("Not allowed");
547 return false;
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());
567 return true;
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();
582 return true;
585 Profile* profile = Profile::FromBrowserContext(browser_context());
586 const base::DictionaryValue* permit_value =
587 EasyUnlockService::Get(profile)->GetPermitAccess();
588 if (permit_value) {
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);
594 return true;
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(),
606 user_public_key);
607 proximity_auth::Base64UrlEncode(enrollment_manager->GetUserPrivateKey(),
608 user_private_key);
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.");
618 SendResponse(true);
619 return;
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();
655 return true;
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);
678 return true;
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();
695 } else {
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());
700 SendResponse(true);
703 return true;
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.");
731 SendResponse(true);
732 return;
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());
747 SendResponse(true);
748 return;
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());
756 SendResponse(true);
757 return;
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(),
768 base::Bind(
769 &EasyUnlockPrivateGetRemoteDevicesFunction::OnPSKDerivedForDevice,
770 this, unlock_key));
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());
803 SendResponse(true);
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);
827 if (!key_manager) {
828 SetError("No EasyUnlockTpmKeyManager.");
829 return false;
831 key_manager->SignUsingTpmKey(
832 EasyUnlockService::Get(profile)->GetUserEmail(),
833 std::string(params->nonce.begin(), params->nonce.end()),
834 base::Bind(&EasyUnlockPrivateGetSignInChallengeFunction::OnDone, this,
835 challenge));
836 } else {
837 OnDone(challenge, std::string());
839 return true;
840 #else // if !defined(OS_CHROMEOS)
841 SetError("Sign-in not supported.");
842 return false;
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()));
852 SendResponse(true);
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()));
871 return true;
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()) {
886 users.push_back(
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);
906 return true;
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);
925 std::string error;
926 if (!device)
927 error = "Invalid Bluetooth device.";
928 else if (!device->IsConnected())
929 error = "Bluetooth device not connected.";
931 if (!error.empty()) {
932 SetError(error);
933 SendResponse(false);
934 return true;
937 device->GetConnectionInfo(base::Bind(
938 &EasyUnlockPrivateGetConnectionInfoFunction::OnConnectionInfo, this));
939 return false;
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());
949 SendResponse(true);
952 EasyUnlockPrivateShowErrorBubbleFunction::
953 EasyUnlockPrivateShowErrorBubbleFunction() {
956 EasyUnlockPrivateShowErrorBubbleFunction::
957 ~EasyUnlockPrivateShowErrorBubbleFunction() {
960 bool EasyUnlockPrivateShowErrorBubbleFunction::RunSync() {
961 content::WebContents* web_contents = GetAssociatedWebContents();
962 if (!web_contents) {
963 SetError("A foreground app window is required.");
964 return true;
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.");
976 return true;
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);
983 anchor_rect +=
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);
989 #else
990 SetError("Not supported on non-Views platforms.");
991 #endif
992 return true;
995 EasyUnlockPrivateHideErrorBubbleFunction::
996 EasyUnlockPrivateHideErrorBubbleFunction() {
999 EasyUnlockPrivateHideErrorBubbleFunction::
1000 ~EasyUnlockPrivateHideErrorBubbleFunction() {
1003 bool EasyUnlockPrivateHideErrorBubbleFunction::RunSync() {
1004 #if defined(TOOLKIT_VIEWS)
1005 HideProximityAuthErrorBubble();
1006 #else
1007 SetError("Not supported on non-Views platforms.");
1008 #endif
1009 return true;
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);
1033 return true;
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;
1056 int connection_id =
1057 GetConnectionManager(browser_context())
1058 ->AddConnection(extension(), connection.Pass(), persistent);
1059 results_ = easy_unlock_private::FindSetupConnection::Results::Create(
1060 connection_id, device_address);
1061 SendResponse(true);
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));
1080 timer_.reset(
1081 new base::OneShotTimer<EasyUnlockPrivateFindSetupConnectionFunction>());
1082 timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(params->time_out),
1083 base::Bind(&EasyUnlockPrivateFindSetupConnectionFunction::
1084 OnConnectionFinderTimedOut,
1085 this));
1087 return true;
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);
1103 results_ =
1104 easy_unlock_private::SetupConnectionStatus::Results::Create(status);
1105 if (status == api::easy_unlock_private::CONNECTION_STATUS_NONE)
1106 SetError("Invalid connectionId");
1107 return true;
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);
1122 if (!success)
1123 SetError("Invalid connectionId.");
1124 return true;
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);
1140 if (!success)
1141 SetError("Invalid connectionId.");
1142 return true;
1145 } // namespace extensions