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/options2/chromeos/bluetooth_options_handler2.h"
8 #include "base/command_line.h"
9 #include "base/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h"
12 #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h"
13 #include "chrome/browser/chromeos/system/runtime_environment.h"
14 #include "chrome/browser/ui/webui/options2/chromeos/system_settings_provider2.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "content/public/browser/web_ui.h"
17 #include "grit/chromium_strings.h"
18 #include "grit/generated_resources.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
20 #include "ui/base/l10n/l10n_util.h"
24 // |UpdateDeviceCallback| takes a variable length list as an argument. The
25 // value stored in each list element is indicated by the following constants.
26 const int kUpdateDeviceAddressIndex
= 0;
27 const int kUpdateDeviceCommandIndex
= 1;
28 const int kUpdateDevicePasskeyIndex
= 2;
35 BluetoothOptionsHandler::BluetoothOptionsHandler() {
38 BluetoothOptionsHandler::~BluetoothOptionsHandler() {
39 if (!CommandLine::ForCurrentProcess()
40 ->HasSwitch(switches::kEnableBluetooth
)) {
44 adapter_
->RemoveObserver(this);
47 void BluetoothOptionsHandler::GetLocalizedValues(
48 DictionaryValue
* localized_strings
) {
49 DCHECK(localized_strings
);
50 localized_strings
->SetString("bluetooth",
51 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH
));
52 localized_strings
->SetString("disableBluetooth",
53 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_DISABLE
));
54 localized_strings
->SetString("enableBluetooth",
55 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_ENABLE
));
56 localized_strings
->SetString("addBluetoothDevice",
57 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_ADD_BLUETOOTH_DEVICE
));
58 localized_strings
->SetString("bluetoothAddDeviceTitle",
59 l10n_util::GetStringUTF16(
60 IDS_OPTIONS_SETTINGS_BLUETOOTH_ADD_DEVICE_TITLE
));
61 localized_strings
->SetString("bluetoothOptionsPageTabTitle",
62 l10n_util::GetStringUTF16(
63 IDS_OPTIONS_SETTINGS_BLUETOOTH_ADD_DEVICE_TITLE
));
64 localized_strings
->SetString("findBluetoothDevices",
65 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_FIND_BLUETOOTH_DEVICES
));
66 localized_strings
->SetString("bluetoothNoDevices",
67 l10n_util::GetStringUTF16(
68 IDS_OPTIONS_SETTINGS_BLUETOOTH_NO_DEVICES
));
69 localized_strings
->SetString("bluetoothNoDevicesFound",
70 l10n_util::GetStringUTF16(
71 IDS_OPTIONS_SETTINGS_BLUETOOTH_NO_DEVICES_FOUND
));
72 localized_strings
->SetString("bluetoothScanning",
73 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_SCANNING
));
74 localized_strings
->SetString("bluetoothDeviceConnected",
75 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECTED
));
76 localized_strings
->SetString("bluetoothDeviceNotConnected",
77 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_NOT_CONNECTED
));
78 localized_strings
->SetString("bluetoothConnectDevice",
79 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT
));
80 localized_strings
->SetString("bluetoothDisconnectDevice",
81 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_DISCONNECT
));
82 localized_strings
->SetString("bluetoothForgetDevice",
83 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_FORGET
));
84 localized_strings
->SetString("bluetoothCancel",
85 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_CANCEL
));
86 localized_strings
->SetString("bluetoothEnterKey",
87 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_KEY
));
88 localized_strings
->SetString("bluetoothAcceptPasskey",
89 l10n_util::GetStringUTF16(
90 IDS_OPTIONS_SETTINGS_BLUETOOTH_ACCEPT_PASSKEY
));
91 localized_strings
->SetString("bluetoothRejectPasskey",
92 l10n_util::GetStringUTF16(
93 IDS_OPTIONS_SETTINGS_BLUETOOTH_REJECT_PASSKEY
));
94 localized_strings
->SetString("bluetoothConfirmPasskey",
95 l10n_util::GetStringUTF16(
96 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONFIRM_PASSKEY_REQUEST
));
97 localized_strings
->SetString("bluetoothEnterPasskey",
98 l10n_util::GetStringUTF16(
99 IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_PASSKEY_REQUEST
));
100 localized_strings
->SetString("bluetoothRemotePasskey",
101 l10n_util::GetStringUTF16(
102 IDS_OPTIONS_SETTINGS_BLUETOOTH_REMOTE_PASSKEY_REQUEST
));
103 localized_strings
->SetString("bluetoothDismissError",
104 l10n_util::GetStringUTF16(
105 IDS_OPTIONS_SETTINGS_BLUETOOTH_DISMISS_ERROR
));
106 localized_strings
->SetString("bluetoothErrorNoDevice",
107 l10n_util::GetStringUTF16(
108 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECTION_FAILED_NO_DEVICE
));
109 localized_strings
->SetString("bluetoothErrorIncorrectPin",
110 l10n_util::GetStringUTF16(
111 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECTION_FAILED_INCORRECT_PIN
));
112 localized_strings
->SetString("bluetoothErrorTimeout",
113 l10n_util::GetStringUTF16(
114 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECTION_FAILED_TIMEOUT
));
115 localized_strings
->SetString("bluetoothErrorConnectionFailed",
116 l10n_util::GetStringUTF16(
117 IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECTION_FAILED
));
120 void BluetoothOptionsHandler::Initialize() {
121 // Bluetooth support is a work in progress. Supress the feature unless
122 // explicitly enabled via a command line flag.
123 if (!CommandLine::ForCurrentProcess()
124 ->HasSwitch(switches::kEnableBluetooth
)) {
128 adapter_
.reset(BluetoothAdapter::CreateDefaultAdapter());
129 adapter_
->AddObserver(this);
131 // Show or hide the bluetooth settings and update the checkbox based
132 // on the current present/powered state.
133 AdapterPresentChanged(adapter_
.get(), adapter_
->IsPresent());
136 void BluetoothOptionsHandler::AdapterPresentChanged(BluetoothAdapter
* adapter
,
138 DCHECK(adapter
== adapter_
.get());
140 web_ui()->CallJavascriptFunction(
141 "options.BrowserOptions.showBluetoothSettings");
143 // Update the checkbox and visibility based on the powered state of the
145 AdapterPoweredChanged(adapter_
.get(), adapter_
->IsPowered());
147 web_ui()->CallJavascriptFunction(
148 "options.BrowserOptions.hideBluetoothSettings");
152 void BluetoothOptionsHandler::AdapterPoweredChanged(BluetoothAdapter
* adapter
,
154 DCHECK(adapter
== adapter_
.get());
155 base::FundamentalValue
checked(powered
);
156 web_ui()->CallJavascriptFunction(
157 "options.BrowserOptions.setBluetoothState", checked
);
160 void BluetoothOptionsHandler::RegisterMessages() {
161 web_ui()->RegisterMessageCallback("bluetoothEnableChange",
162 base::Bind(&BluetoothOptionsHandler::EnableChangeCallback
,
163 base::Unretained(this)));
164 web_ui()->RegisterMessageCallback("findBluetoothDevices",
165 base::Bind(&BluetoothOptionsHandler::FindDevicesCallback
,
166 base::Unretained(this)));
167 web_ui()->RegisterMessageCallback("updateBluetoothDevice",
168 base::Bind(&BluetoothOptionsHandler::UpdateDeviceCallback
,
169 base::Unretained(this)));
170 web_ui()->RegisterMessageCallback("stopBluetoothDeviceDiscovery",
171 base::Bind(&BluetoothOptionsHandler::StopDiscoveryCallback
,
172 base::Unretained(this)));
173 web_ui()->RegisterMessageCallback("getPairedBluetoothDevices",
174 base::Bind(&BluetoothOptionsHandler::GetPairedDevicesCallback
,
175 base::Unretained(this)));
179 void BluetoothOptionsHandler::EnableChangeCallback(
180 const ListValue
* args
) {
181 bool bluetooth_enabled
;
182 args
->GetBoolean(0, &bluetooth_enabled
);
184 adapter_
->SetPowered(bluetooth_enabled
,
185 base::Bind(&BluetoothOptionsHandler::ErrorCallback
,
186 base::Unretained(this)));
189 void BluetoothOptionsHandler::FindDevicesCallback(
190 const ListValue
* args
) {
191 adapter_
->SetDiscovering(true,
192 base::Bind(&BluetoothOptionsHandler::ErrorCallback
,
193 base::Unretained(this)));
196 void BluetoothOptionsHandler::UpdateDeviceCallback(
197 const ListValue
* args
) {
198 // TODO(kevers): Trigger connect/disconnect.
199 int size
= args
->GetSize();
202 args
->GetString(kUpdateDeviceAddressIndex
, &address
);
203 args
->GetString(kUpdateDeviceCommandIndex
, &command
);
204 if (size
> kUpdateDevicePasskeyIndex
) {
205 // Passkey confirmation as part of the pairing process.
207 args
->GetString(kUpdateDevicePasskeyIndex
, &passkey
);
208 DVLOG(1) << "UpdateDeviceCallback: " << address
<< ": " << command
209 << " [" << passkey
<< "]";
211 // Initiating a device connection or disconnecting
212 DVLOG(1) << "UpdateDeviceCallback: " << address
<< ": " << command
;
216 void BluetoothOptionsHandler::StopDiscoveryCallback(
217 const ListValue
* args
) {
218 adapter_
->SetDiscovering(false,
219 base::Bind(&BluetoothOptionsHandler::ErrorCallback
,
220 base::Unretained(this)));
223 void BluetoothOptionsHandler::GetPairedDevicesCallback(
224 const ListValue
* args
) {
225 BluetoothAdapter::DeviceList devices
= adapter_
->GetDevices();
227 for (BluetoothAdapter::DeviceList::iterator iter
= devices
.begin();
228 iter
!= devices
.end(); ++iter
)
229 SendDeviceNotification(*iter
, NULL
);
232 void BluetoothOptionsHandler::SendDeviceNotification(
233 const BluetoothDevice
* device
,
234 base::DictionaryValue
* params
) {
235 base::DictionaryValue js_properties
;
236 js_properties
.SetString("name", device
->GetName());
237 js_properties
.SetString("address", device
->address());
238 js_properties
.SetBoolean("discovered", device
->WasDiscovered());
239 js_properties
.SetBoolean("paired", device
->IsPaired());
240 js_properties
.SetBoolean("connected", device
->IsConnected());
242 js_properties
.MergeDictionary(params
);
244 web_ui()->CallJavascriptFunction(
245 "options.BrowserOptions.addBluetoothDevice",
249 void BluetoothOptionsHandler::RequestConfirmation(
250 const BluetoothDevice
* device
,
252 DictionaryValue params
;
253 params
.SetString("pairing", "bluetoothConfirmPasskey");
254 params
.SetInteger("passkey", passkey
);
255 SendDeviceNotification(device
, ¶ms
);
258 void BluetoothOptionsHandler::DisplayPasskey(
259 const BluetoothDevice
* device
,
262 DictionaryValue params
;
263 params
.SetString("pairing", "bluetoothRemotePasskey");
264 params
.SetInteger("passkey", passkey
);
265 params
.SetInteger("entered", entered
);
266 SendDeviceNotification(device
, ¶ms
);
269 void BluetoothOptionsHandler::RequestPasskey(
270 const BluetoothDevice
* device
) {
271 DictionaryValue params
;
272 params
.SetString("pairing", "bluetoothEnterPasskey");
273 SendDeviceNotification(device
, ¶ms
);
276 void BluetoothOptionsHandler::ReportError(
277 const BluetoothDevice
* device
,
278 ConnectionError error
) {
279 std::string errorCode
;
281 case DEVICE_NOT_FOUND
:
282 errorCode
= "bluetoothErrorNoDevice";
285 errorCode
= "bluetoothErrorIncorrectPin";
287 case CONNECTION_TIMEOUT
:
288 errorCode
= "bluetoothErrorTimeout";
290 case CONNECTION_REJECTED
:
291 errorCode
= "bluetoothErrorConnectionFailed";
294 DictionaryValue params
;
295 params
.SetString("pairing", errorCode
);
296 SendDeviceNotification(device
, ¶ms
);
299 void BluetoothOptionsHandler::DeviceAdded(BluetoothAdapter
* adapter
,
300 BluetoothDevice
* device
) {
301 DCHECK(adapter
== adapter_
.get());
303 SendDeviceNotification(device
, NULL
);
306 void BluetoothOptionsHandler::DeviceChanged(BluetoothAdapter
* adapter
,
307 BluetoothDevice
* device
) {
308 DCHECK(adapter
== adapter_
.get());
310 SendDeviceNotification(device
, NULL
);
313 void BluetoothOptionsHandler::DeviceRemoved(BluetoothAdapter
* adapter
,
314 BluetoothDevice
* device
) {
315 DCHECK(adapter
== adapter_
.get());
318 base::StringValue
address(device
->address());
319 web_ui()->CallJavascriptFunction(
320 "options.BrowserOptions.removeBluetoothDevice",
324 void BluetoothOptionsHandler::ErrorCallback() {
325 // TODO(keybuk): we don't get any form of error response from dbus::
326 // yet, other than an error occurred. I'm going to fix that, then this
327 // gets replaced by genuine error information from the method which we
328 // can act on, rather than a debug log statement.
329 DVLOG(1) << "Failed.";
332 } // namespace options2
333 } // namespace chromeos