Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / webui / options / chromeos / bluetooth_options_handler.cc
blob61fee3d7af7ad837d6794c389be680a937221ebb
1 // Copyright (c) 2012 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/ui/webui/options/chromeos/bluetooth_options_handler.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/command_line.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/grit/generated_resources.h"
15 #include "content/public/browser/web_ui.h"
16 #include "device/bluetooth/bluetooth_adapter.h"
17 #include "device/bluetooth/bluetooth_adapter_factory.h"
18 #include "device/bluetooth/bluetooth_device.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
21 namespace {
23 // |UpdateDeviceCallback| takes a variable length list as an argument. The
24 // value stored in each list element is indicated by the following constants.
25 const int kUpdateDeviceAddressIndex = 0;
26 const int kUpdateDeviceCommandIndex = 1;
27 const int kUpdateDeviceAuthTokenIndex = 2;
29 // |UpdateDeviceCallback| provides a command value of one of the following
30 // constants that indicates what update it is providing to us.
31 const char kConnectCommand[] = "connect";
32 const char kCancelCommand[] = "cancel";
33 const char kAcceptCommand[] = "accept";
34 const char kRejectCommand[] = "reject";
35 const char kDisconnectCommand[] = "disconnect";
36 const char kForgetCommand[] = "forget";
38 // |SendDeviceNotification| may include a pairing parameter whose value
39 // is one of the following constants instructing the UI to perform a certain
40 // action.
41 const char kStartConnecting[] = "bluetoothStartConnecting";
42 const char kEnterPinCode[] = "bluetoothEnterPinCode";
43 const char kEnterPasskey[] = "bluetoothEnterPasskey";
44 const char kRemotePinCode[] = "bluetoothRemotePinCode";
45 const char kRemotePasskey[] = "bluetoothRemotePasskey";
46 const char kConfirmPasskey[] = "bluetoothConfirmPasskey";
48 // An invalid |entered| value to represent the "undefined" value.
49 const int kInvalidEntered = 0xFFFF;
51 } // namespace
53 namespace chromeos {
54 namespace options {
56 BluetoothOptionsHandler::BluetoothOptionsHandler()
57 : should_run_device_discovery_(false),
58 pairing_device_passkey_(1000000),
59 pairing_device_entered_(kInvalidEntered),
60 weak_ptr_factory_(this) {
63 BluetoothOptionsHandler::~BluetoothOptionsHandler() {
64 if (adapter_.get())
65 adapter_->RemoveObserver(this);
68 void BluetoothOptionsHandler::GetLocalizedValues(
69 base::DictionaryValue* localized_strings) {
70 DCHECK(localized_strings);
72 static OptionsStringResource resources[] = {
73 { "bluetooth", IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH },
74 { "disableBluetooth", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISABLE },
75 { "enableBluetooth", IDS_OPTIONS_SETTINGS_BLUETOOTH_ENABLE },
76 { "addBluetoothDevice", IDS_OPTIONS_SETTINGS_ADD_BLUETOOTH_DEVICE },
77 { "bluetoothAddDeviceTitle",
78 IDS_OPTIONS_SETTINGS_BLUETOOTH_ADD_DEVICE_TITLE },
79 { "bluetoothOptionsPageTabTitle",
80 IDS_OPTIONS_SETTINGS_BLUETOOTH_ADD_DEVICE_TITLE },
81 { "findBluetoothDevices", IDS_OPTIONS_SETTINGS_FIND_BLUETOOTH_DEVICES },
82 { "bluetoothNoDevices", IDS_OPTIONS_SETTINGS_BLUETOOTH_NO_DEVICES },
83 { "bluetoothNoDevicesFound",
84 IDS_OPTIONS_SETTINGS_BLUETOOTH_NO_DEVICES_FOUND },
85 { "bluetoothScanning", IDS_OPTIONS_SETTINGS_BLUETOOTH_SCANNING },
86 { "bluetoothScanStopped", IDS_OPTIONS_SETTINGS_BLUETOOTH_SCAN_STOPPED },
87 { "bluetoothDeviceConnecting", IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECTING },
88 { "bluetoothConnectDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT },
89 { "bluetoothDisconnectDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISCONNECT },
90 { "bluetoothForgetDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_FORGET },
91 { "bluetoothCancel", IDS_OPTIONS_SETTINGS_BLUETOOTH_CANCEL },
92 { "bluetoothEnterKey", IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_KEY },
93 { "bluetoothDismissError", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISMISS_ERROR },
95 // Device connecting and pairing.
96 { "bluetoothStartConnecting",
97 IDS_OPTIONS_SETTINGS_BLUETOOTH_START_CONNECTING },
98 { "bluetoothAcceptPasskey",
99 IDS_OPTIONS_SETTINGS_BLUETOOTH_ACCEPT_PASSKEY },
100 { "bluetoothRejectPasskey",
101 IDS_OPTIONS_SETTINGS_BLUETOOTH_REJECT_PASSKEY },
102 { "bluetoothEnterPinCode",
103 IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_PIN_CODE_REQUEST },
104 { "bluetoothEnterPasskey",
105 IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_PASSKEY_REQUEST },
106 { "bluetoothRemotePinCode",
107 IDS_OPTIONS_SETTINGS_BLUETOOTH_REMOTE_PIN_CODE_REQUEST },
108 { "bluetoothRemotePasskey",
109 IDS_OPTIONS_SETTINGS_BLUETOOTH_REMOTE_PASSKEY_REQUEST },
110 { "bluetoothConfirmPasskey",
111 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONFIRM_PASSKEY_REQUEST },
113 // Error messages.
114 { "bluetoothStartDiscoveryFailed",
115 IDS_OPTIONS_SETTINGS_BLUETOOTH_START_DISCOVERY_FAILED },
116 { "bluetoothStopDiscoveryFailed",
117 IDS_OPTIONS_SETTINGS_BLUETOOTH_STOP_DISCOVERY_FAILED },
118 { "bluetoothChangePowerFailed",
119 IDS_OPTIONS_SETTINGS_BLUETOOTH_CHANGE_POWER_FAILED },
120 { "bluetoothConnectUnknownError",
121 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_UNKNOWN_ERROR },
122 { "bluetoothConnectInProgress",
123 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_IN_PROGRESS },
124 { "bluetoothConnectFailed",
125 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_FAILED },
126 { "bluetoothConnectAuthFailed",
127 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_FAILED },
128 { "bluetoothConnectAuthCanceled",
129 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_CANCELED },
130 { "bluetoothConnectAuthRejected",
131 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_REJECTED },
132 { "bluetoothConnectAuthTimeout",
133 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_TIMEOUT },
134 { "bluetoothConnectUnsupportedDevice",
135 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_UNSUPPORTED_DEVICE },
136 { "bluetoothDisconnectFailed",
137 IDS_OPTIONS_SETTINGS_BLUETOOTH_DISCONNECT_FAILED },
138 { "bluetoothForgetFailed",
139 IDS_OPTIONS_SETTINGS_BLUETOOTH_FORGET_FAILED }};
141 RegisterStrings(localized_strings, resources, arraysize(resources));
144 // TODO(kevers): Reorder methods to match ordering in the header file.
146 void BluetoothOptionsHandler::AdapterPresentChanged(
147 device::BluetoothAdapter* adapter,
148 bool present) {
149 DCHECK(adapter == adapter_.get());
150 if (present) {
151 web_ui()->CallJavascriptFunction(
152 "options.BrowserOptions.showBluetoothSettings");
154 // Update the checkbox and visibility based on the powered state of the
155 // new adapter.
156 AdapterPoweredChanged(adapter_.get(), adapter_->IsPowered());
157 } else {
158 web_ui()->CallJavascriptFunction(
159 "options.BrowserOptions.hideBluetoothSettings");
163 void BluetoothOptionsHandler::AdapterPoweredChanged(
164 device::BluetoothAdapter* adapter,
165 bool powered) {
166 DCHECK(adapter == adapter_.get());
167 base::FundamentalValue checked(powered);
168 web_ui()->CallJavascriptFunction(
169 "options.BrowserOptions.setBluetoothState", checked);
171 // If the "Add device" overlay is visible, dismiss it.
172 if (!powered) {
173 web_ui()->CallJavascriptFunction(
174 "options.BluetoothOptions.dismissOverlay");
178 void BluetoothOptionsHandler::AdapterDiscoveringChanged(
179 device::BluetoothAdapter* adapter,
180 bool discovering) {
181 DCHECK(adapter == adapter_.get());
182 base::FundamentalValue discovering_value(discovering);
183 web_ui()->CallJavascriptFunction(
184 "options.BluetoothOptions.updateDiscoveryState", discovering_value);
187 void BluetoothOptionsHandler::RegisterMessages() {
188 web_ui()->RegisterMessageCallback("bluetoothEnableChange",
189 base::Bind(&BluetoothOptionsHandler::EnableChangeCallback,
190 base::Unretained(this)));
191 web_ui()->RegisterMessageCallback("findBluetoothDevices",
192 base::Bind(&BluetoothOptionsHandler::FindDevicesCallback,
193 base::Unretained(this)));
194 web_ui()->RegisterMessageCallback("updateBluetoothDevice",
195 base::Bind(&BluetoothOptionsHandler::UpdateDeviceCallback,
196 base::Unretained(this)));
197 web_ui()->RegisterMessageCallback("stopBluetoothDeviceDiscovery",
198 base::Bind(&BluetoothOptionsHandler::StopDiscoveryCallback,
199 base::Unretained(this)));
200 web_ui()->RegisterMessageCallback("getPairedBluetoothDevices",
201 base::Bind(&BluetoothOptionsHandler::GetPairedDevicesCallback,
202 base::Unretained(this)));
205 void BluetoothOptionsHandler::InitializeHandler() {
206 device::BluetoothAdapterFactory::GetAdapter(
207 base::Bind(&BluetoothOptionsHandler::InitializeAdapter,
208 weak_ptr_factory_.GetWeakPtr()));
211 void BluetoothOptionsHandler::InitializePage() {
212 // Show or hide the bluetooth settings and update the checkbox based
213 // on the current present/powered state.
214 AdapterPresentChanged(adapter_.get(), adapter_->IsPresent());
216 // Automatically start device discovery if the "Add Bluetooth Device"
217 // overlay is visible.
218 web_ui()->CallJavascriptFunction(
219 "options.BluetoothOptions.startDeviceDiscovery");
222 void BluetoothOptionsHandler::InitializeAdapter(
223 scoped_refptr<device::BluetoothAdapter> adapter) {
224 adapter_ = adapter;
225 CHECK(adapter_.get());
226 adapter_->AddObserver(this);
229 void BluetoothOptionsHandler::EnableChangeCallback(
230 const base::ListValue* args) {
231 bool bluetooth_enabled;
232 args->GetBoolean(0, &bluetooth_enabled);
234 adapter_->SetPowered(bluetooth_enabled,
235 base::Bind(&base::DoNothing),
236 base::Bind(&BluetoothOptionsHandler::EnableChangeError,
237 weak_ptr_factory_.GetWeakPtr()));
240 void BluetoothOptionsHandler::EnableChangeError() {
241 VLOG(1) << "Failed to change power state.";
242 ReportError("bluetoothChangePowerFailed", std::string());
245 void BluetoothOptionsHandler::FindDevicesCallback(
246 const base::ListValue* args) {
247 if (discovery_session_.get() && discovery_session_->IsActive()) {
248 VLOG(1) << "Already have an active discovery session.";
249 return;
251 should_run_device_discovery_ = true;
252 adapter_->StartDiscoverySession(
253 base::Bind(&BluetoothOptionsHandler::OnStartDiscoverySession,
254 weak_ptr_factory_.GetWeakPtr()),
255 base::Bind(&BluetoothOptionsHandler::FindDevicesError,
256 weak_ptr_factory_.GetWeakPtr()));
259 void BluetoothOptionsHandler::OnStartDiscoverySession(
260 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
261 // If the discovery session was returned after a request to stop discovery
262 // (e.g. the "Add Device" dialog was dismissed), don't claim the discovery
263 // session and let it clean up.
264 if (!should_run_device_discovery_)
265 return;
266 discovery_session_ = discovery_session.Pass();
269 void BluetoothOptionsHandler::FindDevicesError() {
270 VLOG(1) << "Failed to start discovery.";
271 ReportError("bluetoothStartDiscoveryFailed", std::string());
272 if (!adapter_.get())
273 return;
274 base::FundamentalValue discovering(adapter_->IsDiscovering());
275 web_ui()->CallJavascriptFunction(
276 "options.BluetoothOptions.updateDiscoveryState", discovering);
279 void BluetoothOptionsHandler::UpdateDeviceCallback(
280 const base::ListValue* args) {
281 std::string address;
282 args->GetString(kUpdateDeviceAddressIndex, &address);
284 device::BluetoothDevice* device = adapter_->GetDevice(address);
285 if (!device)
286 return;
288 std::string command;
289 args->GetString(kUpdateDeviceCommandIndex, &command);
291 if (command == kConnectCommand) {
292 int size = args->GetSize();
293 if (size > kUpdateDeviceAuthTokenIndex) {
294 // PIN code or Passkey entry during the pairing process.
295 std::string auth_token;
296 args->GetString(kUpdateDeviceAuthTokenIndex, &auth_token);
298 if (device->ExpectingPinCode()) {
299 DeviceConnecting(device);
300 // PIN Code is an array of 1 to 16 8-bit bytes, the usual
301 // interpretation, and the one shared by BlueZ, is a UTF-8 string
302 // of as many characters that will fit in that space, thus we
303 // can use the auth token from JavaScript unmodified.
304 VLOG(1) << "PIN Code supplied: " << address << ": " << auth_token;
305 device->SetPinCode(auth_token);
306 } else if (device->ExpectingPasskey()) {
307 DeviceConnecting(device);
308 // Passkey is a numeric in the range 0-999999, in this case the
309 // JavaScript code should have ensured the auth token string only
310 // contains digits so a simple conversion is sufficient. In the
311 // failure case, just use 0 since that's the most likely Passkey
312 // anyway, and if it's refused the device will request a new one.
313 unsigned passkey = 0;
314 base::StringToUint(auth_token, &passkey);
316 VLOG(1) << "Passkey supplied: " << address << ": " << passkey;
317 device->SetPasskey(passkey);
318 } else {
319 LOG(WARNING) << "Auth token supplied after pairing ended: " << address
320 << ": " << auth_token;
322 } else {
323 // Determine if the device supports pairing:
324 PairingDelegate* delegate = NULL;
325 if (device->IsPairable())
326 delegate = this;
328 // Connection request.
329 VLOG(1) << "Connect: " << address;
330 device->Connect(
331 delegate,
332 base::Bind(&BluetoothOptionsHandler::Connected,
333 weak_ptr_factory_.GetWeakPtr()),
334 base::Bind(&BluetoothOptionsHandler::ConnectError,
335 weak_ptr_factory_.GetWeakPtr(),
336 device->GetAddress()));
338 } else if (command == kCancelCommand) {
339 // Cancel pairing.
340 VLOG(1) << "Cancel pairing: " << address;
341 device->CancelPairing();
342 } else if (command == kAcceptCommand) {
343 DeviceConnecting(device);
344 // Confirm displayed Passkey.
345 VLOG(1) << "Confirm pairing: " << address;
346 device->ConfirmPairing();
347 } else if (command == kRejectCommand) {
348 // Reject displayed Passkey.
349 VLOG(1) << "Reject pairing: " << address;
350 device->RejectPairing();
351 } else if (command == kDisconnectCommand) {
352 // Disconnect from device.
353 VLOG(1) << "Disconnect device: " << address;
354 device->Disconnect(
355 base::Bind(&base::DoNothing),
356 base::Bind(&BluetoothOptionsHandler::DisconnectError,
357 weak_ptr_factory_.GetWeakPtr(),
358 device->GetAddress()));
359 } else if (command == kForgetCommand) {
360 // Disconnect from device and delete pairing information.
361 VLOG(1) << "Forget device: " << address;
362 device->Forget(base::Bind(&BluetoothOptionsHandler::ForgetError,
363 weak_ptr_factory_.GetWeakPtr(),
364 device->GetAddress()));
365 } else {
366 LOG(WARNING) << "Unknown updateBluetoothDevice command: " << command;
370 void BluetoothOptionsHandler::Connected() {
371 // Invalidate the local cache.
372 pairing_device_address_.clear();
373 pairing_device_entered_ = kInvalidEntered;
375 web_ui()->CallJavascriptFunction(
376 "options.BluetoothPairing.dismissDialog");
379 void BluetoothOptionsHandler::ConnectError(
380 const std::string& address,
381 device::BluetoothDevice::ConnectErrorCode error_code) {
382 const char* error_name = NULL;
384 // Invalidate the local cache.
385 pairing_device_address_.clear();
386 pairing_device_entered_ = kInvalidEntered;
388 VLOG(1) << "Failed to connect to device: " << address;
389 switch (error_code) {
390 case device::BluetoothDevice::ERROR_UNKNOWN:
391 error_name = "bluetoothConnectUnknownError";
392 break;
393 case device::BluetoothDevice::ERROR_INPROGRESS:
394 error_name = "bluetoothConnectInProgress";
395 break;
396 case device::BluetoothDevice::ERROR_FAILED:
397 error_name = "bluetoothConnectFailed";
398 break;
399 case device::BluetoothDevice::ERROR_AUTH_FAILED:
400 error_name = "bluetoothConnectAuthFailed";
401 break;
402 case device::BluetoothDevice::ERROR_AUTH_CANCELED:
403 error_name = "bluetoothConnectAuthCanceled";
404 break;
405 case device::BluetoothDevice::ERROR_AUTH_REJECTED:
406 error_name = "bluetoothConnectAuthRejected";
407 break;
408 case device::BluetoothDevice::ERROR_AUTH_TIMEOUT:
409 error_name = "bluetoothConnectAuthTimeout";
410 break;
411 case device::BluetoothDevice::ERROR_UNSUPPORTED_DEVICE:
412 error_name = "bluetoothConnectUnsupportedDevice";
413 break;
415 // Report an error only if there's an error to report.
416 if (error_name)
417 ReportError(error_name, address);
420 void BluetoothOptionsHandler::DisconnectError(const std::string& address) {
421 VLOG(1) << "Failed to disconnect from device: " << address;
422 ReportError("bluetoothDisconnectFailed", address);
425 void BluetoothOptionsHandler::ForgetError(const std::string& address) {
426 VLOG(1) << "Failed to disconnect and unpair device: " << address;
427 ReportError("bluetoothForgetFailed", address);
430 void BluetoothOptionsHandler::StopDiscoveryCallback(
431 const base::ListValue* args) {
432 should_run_device_discovery_ = false;
433 if (!discovery_session_.get() || !discovery_session_->IsActive()) {
434 VLOG(1) << "No active discovery session.";
435 return;
437 discovery_session_->Stop(
438 base::Bind(&base::DoNothing),
439 base::Bind(&BluetoothOptionsHandler::StopDiscoveryError,
440 weak_ptr_factory_.GetWeakPtr()));
443 void BluetoothOptionsHandler::StopDiscoveryError() {
444 VLOG(1) << "Failed to stop discovery.";
445 ReportError("bluetoothStopDiscoveryFailed", std::string());
448 void BluetoothOptionsHandler::GetPairedDevicesCallback(
449 const base::ListValue* args) {
450 device::BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
452 for (device::BluetoothAdapter::DeviceList::iterator iter = devices.begin();
453 iter != devices.end(); ++iter)
454 SendDeviceNotification(*iter, NULL);
457 void BluetoothOptionsHandler::SendDeviceNotification(
458 const device::BluetoothDevice* device,
459 base::DictionaryValue* params) {
460 base::DictionaryValue js_properties;
461 js_properties.SetString("name", device->GetName());
462 js_properties.SetString("address", device->GetAddress());
463 js_properties.SetBoolean("paired", device->IsPaired());
464 js_properties.SetBoolean("connected", device->IsConnected());
465 js_properties.SetBoolean("connecting", device->IsConnecting());
466 js_properties.SetBoolean("connectable", device->IsConnectable());
467 if (params)
468 js_properties.MergeDictionary(params);
470 // Use the cached values to update js_property.
471 if (device->GetAddress() == pairing_device_address_) {
472 std::string pairing;
473 if (!js_properties.GetString("pairing", &pairing)) {
474 pairing = pairing_device_pairing_;
475 js_properties.SetString("pairing", pairing);
477 if (pairing == kRemotePinCode && !js_properties.HasKey("pincode"))
478 js_properties.SetString("pincode", pairing_device_pincode_);
479 if (pairing == kRemotePasskey && !js_properties.HasKey("passkey"))
480 js_properties.SetInteger("passkey", pairing_device_passkey_);
481 if ((pairing == kRemotePinCode || pairing == kRemotePasskey) &&
482 !js_properties.HasKey("entered") &&
483 pairing_device_entered_ != kInvalidEntered) {
484 js_properties.SetInteger("entered", pairing_device_entered_);
488 // Update the cache with the new information.
489 if (js_properties.HasKey("pairing")) {
490 pairing_device_address_ = device->GetAddress();
491 js_properties.GetString("pairing", &pairing_device_pairing_);
492 js_properties.GetString("pincode", &pairing_device_pincode_);
493 js_properties.GetInteger("passkey", &pairing_device_passkey_);
494 if (!js_properties.GetInteger("entered", &pairing_device_entered_))
495 pairing_device_entered_ = kInvalidEntered;
498 web_ui()->CallJavascriptFunction(
499 "options.BrowserOptions.addBluetoothDevice",
500 js_properties);
503 void BluetoothOptionsHandler::RequestPinCode(device::BluetoothDevice* device) {
504 base::DictionaryValue params;
505 params.SetString("pairing", kEnterPinCode);
506 SendDeviceNotification(device, &params);
509 void BluetoothOptionsHandler::RequestPasskey(device::BluetoothDevice* device) {
510 base::DictionaryValue params;
511 params.SetString("pairing", kEnterPasskey);
512 SendDeviceNotification(device, &params);
515 void BluetoothOptionsHandler::DisplayPinCode(device::BluetoothDevice* device,
516 const std::string& pincode) {
517 base::DictionaryValue params;
518 params.SetString("pairing", kRemotePinCode);
519 params.SetString("pincode", pincode);
520 SendDeviceNotification(device, &params);
523 void BluetoothOptionsHandler::DisplayPasskey(device::BluetoothDevice* device,
524 uint32 passkey) {
525 base::DictionaryValue params;
526 params.SetString("pairing", kRemotePasskey);
527 params.SetInteger("passkey", passkey);
528 SendDeviceNotification(device, &params);
531 void BluetoothOptionsHandler::KeysEntered(device::BluetoothDevice* device,
532 uint32 entered) {
533 base::DictionaryValue params;
534 params.SetInteger("entered", entered);
535 SendDeviceNotification(device, &params);
538 void BluetoothOptionsHandler::ConfirmPasskey(device::BluetoothDevice* device,
539 uint32 passkey) {
540 base::DictionaryValue params;
541 params.SetString("pairing", kConfirmPasskey);
542 params.SetInteger("passkey", passkey);
543 SendDeviceNotification(device, &params);
546 void BluetoothOptionsHandler::AuthorizePairing(
547 device::BluetoothDevice* device) {
548 // There is never any circumstance where this will be called, since the
549 // options handler will only be used for outgoing pairing requests, but
550 // play it safe.
551 device->ConfirmPairing();
554 void BluetoothOptionsHandler::ReportError(
555 const std::string& error,
556 const std::string& address) {
557 base::DictionaryValue properties;
558 properties.SetString("message", error);
559 properties.SetString("address", address);
560 web_ui()->CallJavascriptFunction(
561 "options.BluetoothPairing.showMessage",
562 properties);
565 void BluetoothOptionsHandler::DeviceAdded(device::BluetoothAdapter* adapter,
566 device::BluetoothDevice* device) {
567 DCHECK(adapter == adapter_.get());
568 DCHECK(device);
569 SendDeviceNotification(device, NULL);
572 void BluetoothOptionsHandler::DeviceChanged(device::BluetoothAdapter* adapter,
573 device::BluetoothDevice* device) {
574 DCHECK(adapter == adapter_.get());
575 DCHECK(device);
576 SendDeviceNotification(device, NULL);
579 void BluetoothOptionsHandler::DeviceRemoved(device::BluetoothAdapter* adapter,
580 device::BluetoothDevice* device) {
581 DCHECK(adapter == adapter_.get());
582 DCHECK(device);
584 // Invalidate the local cache if the pairing device is removed.
585 if (pairing_device_address_ == device->GetAddress()) {
586 pairing_device_address_.clear();
587 pairing_device_entered_ = kInvalidEntered;
590 base::StringValue address(device->GetAddress());
591 web_ui()->CallJavascriptFunction(
592 "options.BrowserOptions.removeBluetoothDevice",
593 address);
596 void BluetoothOptionsHandler::DeviceConnecting(
597 device::BluetoothDevice* device) {
598 DCHECK(device);
599 base::DictionaryValue params;
600 params.SetString("pairing", kStartConnecting);
601 SendDeviceNotification(device, &params);
604 } // namespace options
605 } // namespace chromeos