15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_factory.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_device.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |UpdateDeviceCallback| takes a variable length list as an argument. The 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value stored in each list element is indicated by the following constants. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kUpdateDeviceAddressIndex = 0; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kUpdateDeviceCommandIndex = 1; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kUpdateDeviceAuthTokenIndex = 2; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |UpdateDeviceCallback| provides a command value of one of the following 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constants that indicates what update it is providing to us. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kConnectCommand[] = "connect"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kCancelCommand[] = "cancel"; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAcceptCommand[] = "accept"; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRejectCommand[] = "reject"; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDisconnectCommand[] = "disconnect"; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kForgetCommand[] = "forget"; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |SendDeviceNotification| may include a pairing parameter whose value 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is one of the following constants instructing the UI to perform a certain 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// action. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kStartConnecting[] = "bluetoothStartConnecting"; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEnterPinCode[] = "bluetoothEnterPinCode"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEnterPasskey[] = "bluetoothEnterPasskey"; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRemotePinCode[] = "bluetoothRemotePinCode"; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRemotePasskey[] = "bluetoothRemotePasskey"; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kConfirmPasskey[] = "bluetoothConfirmPasskey"; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// An invalid |entered| value to represent the "undefined" value. 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kInvalidEntered = 0xFFFF; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace options { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothOptionsHandler::BluetoothOptionsHandler() 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : should_run_device_discovery_(false), 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_device_passkey_(1000000), 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_device_entered_(kInvalidEntered), 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_(this) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothOptionsHandler::~BluetoothOptionsHandler() { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (adapter_.get()) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) adapter_->RemoveObserver(this); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::GetLocalizedValues( 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* localized_strings) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(localized_strings); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static OptionsStringResource resources[] = { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetooth", IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH }, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "disableBluetooth", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISABLE }, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "enableBluetooth", IDS_OPTIONS_SETTINGS_BLUETOOTH_ENABLE }, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "addBluetoothDevice", IDS_OPTIONS_SETTINGS_ADD_BLUETOOTH_DEVICE }, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothAddDeviceTitle", 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_ADD_DEVICE_TITLE }, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothOptionsPageTabTitle", 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_ADD_DEVICE_TITLE }, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "findBluetoothDevices", IDS_OPTIONS_SETTINGS_FIND_BLUETOOTH_DEVICES }, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothNoDevices", IDS_OPTIONS_SETTINGS_BLUETOOTH_NO_DEVICES }, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothNoDevicesFound", 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_NO_DEVICES_FOUND }, 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { "bluetoothScanning", IDS_OPTIONS_SETTINGS_BLUETOOTH_SCANNING }, 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch { "bluetoothScanStopped", IDS_OPTIONS_SETTINGS_BLUETOOTH_SCAN_STOPPED }, 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { "bluetoothDeviceConnecting", IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECTING }, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothConnectDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT }, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothDisconnectDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISCONNECT }, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothForgetDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_FORGET }, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothCancel", IDS_OPTIONS_SETTINGS_BLUETOOTH_CANCEL }, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothEnterKey", IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_KEY }, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothDismissError", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISMISS_ERROR }, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Device connecting and pairing. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothStartConnecting", 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_START_CONNECTING }, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothAcceptPasskey", 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_ACCEPT_PASSKEY }, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothRejectPasskey", 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_REJECT_PASSKEY }, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothEnterPinCode", 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_PIN_CODE_REQUEST }, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothEnterPasskey", 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_PASSKEY_REQUEST }, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothRemotePinCode", 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_REMOTE_PIN_CODE_REQUEST }, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothRemotePasskey", 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_REMOTE_PASSKEY_REQUEST }, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothConfirmPasskey", 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONFIRM_PASSKEY_REQUEST }, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Error messages. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothStartDiscoveryFailed", 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_START_DISCOVERY_FAILED }, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothStopDiscoveryFailed", 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_STOP_DISCOVERY_FAILED }, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothChangePowerFailed", 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CHANGE_POWER_FAILED }, 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { "bluetoothConnectUnknownError", 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_UNKNOWN_ERROR }, 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { "bluetoothConnectInProgress", 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_IN_PROGRESS }, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothConnectFailed", 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_FAILED }, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { "bluetoothConnectAuthFailed", 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_FAILED }, 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { "bluetoothConnectAuthCanceled", 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_CANCELED }, 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { "bluetoothConnectAuthRejected", 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_REJECTED }, 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { "bluetoothConnectAuthTimeout", 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_TIMEOUT }, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { "bluetoothConnectUnsupportedDevice", 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_UNSUPPORTED_DEVICE }, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothDisconnectFailed", 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_DISCONNECT_FAILED }, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "bluetoothForgetFailed", 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_OPTIONS_SETTINGS_BLUETOOTH_FORGET_FAILED }}; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegisterStrings(localized_strings, resources, arraysize(resources)); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kevers): Reorder methods to match ordering in the header file. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::AdapterPresentChanged( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device::BluetoothAdapter* adapter, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool present) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(adapter == adapter_.get()); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (present) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options.BrowserOptions.showBluetoothSettings"); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the checkbox and visibility based on the powered state of the 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new adapter. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdapterPoweredChanged(adapter_.get(), adapter_->IsPowered()); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options.BrowserOptions.hideBluetoothSettings"); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::AdapterPoweredChanged( 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device::BluetoothAdapter* adapter, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool powered) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(adapter == adapter_.get()); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::FundamentalValue checked(powered); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options.BrowserOptions.setBluetoothState", checked); 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // If the "Add device" overlay is visible, dismiss it. 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!powered) { 173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch web_ui()->CallJavascriptFunction( 174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "options.BluetoothOptions.dismissOverlay"); 175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid BluetoothOptionsHandler::AdapterDiscoveringChanged( 179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch device::BluetoothAdapter* adapter, 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool discovering) { 181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(adapter == adapter_.get()); 182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::FundamentalValue discovering_value(discovering); 183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch web_ui()->CallJavascriptFunction( 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "options.BluetoothOptions.updateDiscoveryState", discovering_value); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::RegisterMessages() { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("bluetoothEnableChange", 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::EnableChangeCallback, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("findBluetoothDevices", 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::FindDevicesCallback, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("updateBluetoothDevice", 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::UpdateDeviceCallback, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("stopBluetoothDeviceDiscovery", 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::StopDiscoveryCallback, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("getPairedBluetoothDevices", 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::GetPairedDevicesCallback, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::InitializeHandler() { 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device::BluetoothAdapterFactory::GetAdapter( 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&BluetoothOptionsHandler::InitializeAdapter, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::InitializePage() { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Show or hide the bluetooth settings and update the checkbox based 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the current present/powered state. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdapterPresentChanged(adapter_.get(), adapter_->IsPresent()); 215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Automatically start device discovery if the "Add Bluetooth Device" 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // overlay is visible. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 219effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "options.BluetoothOptions.startDeviceDiscovery"); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothOptionsHandler::InitializeAdapter( 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<device::BluetoothAdapter> adapter) { 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) adapter_ = adapter; 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK(adapter_.get()); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) adapter_->AddObserver(this); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::EnableChangeCallback( 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* args) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bluetooth_enabled; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->GetBoolean(0, &bluetooth_enabled); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) adapter_->SetPowered(bluetooth_enabled, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&base::DoNothing), 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::EnableChangeError, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::EnableChangeError() { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Failed to change power state."; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("bluetoothChangePowerFailed", std::string()); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::FindDevicesCallback( 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* args) { 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (discovery_session_.get() && discovery_session_->IsActive()) { 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Already have an active discovery session."; 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) should_run_device_discovery_ = true; 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) adapter_->StartDiscoverySession( 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::OnStartDiscoverySession, 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::FindDevicesError, 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothOptionsHandler::OnStartDiscoverySession( 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the discovery session was returned after a request to stop discovery 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (e.g. the "Add Device" dialog was dismissed), don't claim the discovery 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // session and let it clean up. 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!should_run_device_discovery_) 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_session_ = discovery_session.Pass(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::FindDevicesError() { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Failed to start discovery."; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("bluetoothStartDiscoveryFailed", std::string()); 272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!adapter_.get()) 273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::FundamentalValue discovering(adapter_->IsDiscovering()); 275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch web_ui()->CallJavascriptFunction( 276effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "options.BluetoothOptions.updateDiscoveryState", discovering); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::UpdateDeviceCallback( 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* args) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string address; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->GetString(kUpdateDeviceAddressIndex, &address); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device::BluetoothDevice* device = adapter_->GetDevice(address); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!device) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string command; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->GetString(kUpdateDeviceCommandIndex, &command); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command == kConnectCommand) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = args->GetSize(); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size > kUpdateDeviceAuthTokenIndex) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PIN code or Passkey entry during the pairing process. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string auth_token; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->GetString(kUpdateDeviceAuthTokenIndex, &auth_token); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (device->ExpectingPinCode()) { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceConnecting(device); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PIN Code is an array of 1 to 16 8-bit bytes, the usual 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interpretation, and the one shared by BlueZ, is a UTF-8 string 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of as many characters that will fit in that space, thus we 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can use the auth token from JavaScript unmodified. 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "PIN Code supplied: " << address << ": " << auth_token; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->SetPinCode(auth_token); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (device->ExpectingPasskey()) { 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceConnecting(device); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Passkey is a numeric in the range 0-999999, in this case the 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JavaScript code should have ensured the auth token string only 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contains digits so a simple conversion is sufficient. In the 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // failure case, just use 0 since that's the most likely Passkey 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // anyway, and if it's refused the device will request a new one. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned passkey = 0; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringToUint(auth_token, &passkey); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Passkey supplied: " << address << ": " << passkey; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->SetPasskey(passkey); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Auth token supplied after pairing ended: " << address 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": " << auth_token; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determine if the device supports pairing: 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PairingDelegate* delegate = NULL; 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (device->IsPairable()) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate = this; 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connection request. 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Connect: " << address; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->Connect( 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate, 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&BluetoothOptionsHandler::Connected, 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::ConnectError, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) device->GetAddress())); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (command == kCancelCommand) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel pairing. 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Cancel pairing: " << address; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->CancelPairing(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (command == kAcceptCommand) { 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceConnecting(device); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Confirm displayed Passkey. 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Confirm pairing: " << address; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->ConfirmPairing(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (command == kRejectCommand) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reject displayed Passkey. 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Reject pairing: " << address; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->RejectPairing(); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (command == kDisconnectCommand) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disconnect from device. 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Disconnect device: " << address; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->Disconnect( 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&base::DoNothing), 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::DisconnectError, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) device->GetAddress())); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (command == kForgetCommand) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disconnect from device and delete pairing information. 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Forget device: " << address; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->Forget(base::Bind(&BluetoothOptionsHandler::ForgetError, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) device->GetAddress())); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unknown updateBluetoothDevice command: " << command; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BluetoothOptionsHandler::Connected() { 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Invalidate the local cache. 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_address_.clear(); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_entered_ = kInvalidEntered; 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_ui()->CallJavascriptFunction( 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "options.BluetoothPairing.dismissDialog"); 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothOptionsHandler::ConnectError( 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& address, 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device::BluetoothDevice::ConnectErrorCode error_code) { 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* error_name = NULL; 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Invalidate the local cache. 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_address_.clear(); 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_entered_ = kInvalidEntered; 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Failed to connect to device: " << address; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (error_code) { 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case device::BluetoothDevice::ERROR_UNKNOWN: 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_name = "bluetoothConnectUnknownError"; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case device::BluetoothDevice::ERROR_INPROGRESS: 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_name = "bluetoothConnectInProgress"; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case device::BluetoothDevice::ERROR_FAILED: 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_name = "bluetoothConnectFailed"; 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case device::BluetoothDevice::ERROR_AUTH_FAILED: 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_name = "bluetoothConnectAuthFailed"; 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case device::BluetoothDevice::ERROR_AUTH_CANCELED: 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_name = "bluetoothConnectAuthCanceled"; 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case device::BluetoothDevice::ERROR_AUTH_REJECTED: 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_name = "bluetoothConnectAuthRejected"; 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case device::BluetoothDevice::ERROR_AUTH_TIMEOUT: 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_name = "bluetoothConnectAuthTimeout"; 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case device::BluetoothDevice::ERROR_UNSUPPORTED_DEVICE: 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_name = "bluetoothConnectUnsupportedDevice"; 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Report an error only if there's an error to report. 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error_name) 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReportError(error_name, address); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::DisconnectError(const std::string& address) { 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Failed to disconnect from device: " << address; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("bluetoothDisconnectFailed", address); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::ForgetError(const std::string& address) { 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Failed to disconnect and unpair device: " << address; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("bluetoothForgetFailed", address); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::StopDiscoveryCallback( 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* args) { 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) should_run_device_discovery_ = false; 433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!discovery_session_.get() || !discovery_session_->IsActive()) { 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "No active discovery session."; 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_session_->Stop( 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&base::DoNothing), 439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothOptionsHandler::StopDiscoveryError, 440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::StopDiscoveryError() { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Failed to stop discovery."; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("bluetoothStopDiscoveryFailed", std::string()); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::GetPairedDevicesCallback( 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* args) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device::BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (device::BluetoothAdapter::DeviceList::iterator iter = devices.begin(); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != devices.end(); ++iter) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDeviceNotification(*iter, NULL); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::SendDeviceNotification( 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const device::BluetoothDevice* device, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* params) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue js_properties; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_properties.SetString("name", device->GetName()); 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.SetString("address", device->GetAddress()); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_properties.SetBoolean("paired", device->IsPaired()); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_properties.SetBoolean("connected", device->IsConnected()); 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.SetBoolean("connecting", device->IsConnecting()); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) js_properties.SetBoolean("connectable", device->IsConnectable()); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (params) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_properties.MergeDictionary(params); 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Use the cached values to update js_property. 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (device->GetAddress() == pairing_device_address_) { 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string pairing; 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!js_properties.GetString("pairing", &pairing)) { 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing = pairing_device_pairing_; 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.SetString("pairing", pairing); 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pairing == kRemotePinCode && !js_properties.HasKey("pincode")) 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.SetString("pincode", pairing_device_pincode_); 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pairing == kRemotePasskey && !js_properties.HasKey("passkey")) 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.SetInteger("passkey", pairing_device_passkey_); 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((pairing == kRemotePinCode || pairing == kRemotePasskey) && 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !js_properties.HasKey("entered") && 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_entered_ != kInvalidEntered) { 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.SetInteger("entered", pairing_device_entered_); 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Update the cache with the new information. 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (js_properties.HasKey("pairing")) { 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_address_ = device->GetAddress(); 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.GetString("pairing", &pairing_device_pairing_); 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.GetString("pincode", &pairing_device_pincode_); 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) js_properties.GetInteger("passkey", &pairing_device_passkey_); 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!js_properties.GetInteger("entered", &pairing_device_entered_)) 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_entered_ = kInvalidEntered; 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options.BrowserOptions.addBluetoothDevice", 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_properties); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::RequestPinCode(device::BluetoothDevice* device) { 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.SetString("pairing", kEnterPinCode); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDeviceNotification(device, ¶ms); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::RequestPasskey(device::BluetoothDevice* device) { 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.SetString("pairing", kEnterPasskey); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDeviceNotification(device, ¶ms); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::DisplayPinCode(device::BluetoothDevice* device, 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& pincode) { 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.SetString("pairing", kRemotePinCode); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.SetString("pincode", pincode); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDeviceNotification(device, ¶ms); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::DisplayPasskey(device::BluetoothDevice* device, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 passkey) { 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.SetString("pairing", kRemotePasskey); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.SetInteger("passkey", passkey); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDeviceNotification(device, ¶ms); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BluetoothOptionsHandler::KeysEntered(device::BluetoothDevice* device, 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32 entered) { 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("entered", entered); 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendDeviceNotification(device, ¶ms); 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::ConfirmPasskey(device::BluetoothDevice* device, 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 passkey) { 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.SetString("pairing", kConfirmPasskey); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.SetInteger("passkey", passkey); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDeviceNotification(device, ¶ms); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothOptionsHandler::AuthorizePairing( 547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device::BluetoothDevice* device) { 548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There is never any circumstance where this will be called, since the 549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // options handler will only be used for outgoing pairing requests, but 550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // play it safe. 551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device->ConfirmPairing(); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::ReportError( 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error, 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& address) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue properties; 5586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) properties.SetString("message", error); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties.SetString("address", address); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options.BluetoothPairing.showMessage", 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::DeviceAdded(device::BluetoothAdapter* adapter, 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device::BluetoothDevice* device) { 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(adapter == adapter_.get()); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(device); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDeviceNotification(device, NULL); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::DeviceChanged(device::BluetoothAdapter* adapter, 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device::BluetoothDevice* device) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(adapter == adapter_.get()); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(device); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDeviceNotification(device, NULL); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothOptionsHandler::DeviceRemoved(device::BluetoothAdapter* adapter, 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device::BluetoothDevice* device) { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(adapter == adapter_.get()); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(device); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Invalidate the local cache if the pairing device is removed. 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pairing_device_address_ == device->GetAddress()) { 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_address_.clear(); 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_device_entered_ = kInvalidEntered; 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringValue address(device->GetAddress()); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options.BrowserOptions.removeBluetoothDevice", 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothOptionsHandler::DeviceConnecting( 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device::BluetoothDevice* device) { 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(device); 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("pairing", kStartConnecting); 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendDeviceNotification(device, ¶ms); 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace options 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 606