bluetooth: fix issues with device removal
[chromium-blink-merge.git] / chrome / browser / ui / webui / options2 / chromeos / bluetooth_options_handler2.cc
blob9727cab3b73c13d71357998996504c0fff0818f6
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"
7 #include "base/bind.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"
22 namespace {
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;
30 } // namespace
32 namespace chromeos {
33 namespace options2 {
35 BluetoothOptionsHandler::BluetoothOptionsHandler() {
38 BluetoothOptionsHandler::~BluetoothOptionsHandler() {
39 if (!CommandLine::ForCurrentProcess()
40 ->HasSwitch(switches::kEnableBluetooth)) {
41 return;
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)) {
125 return;
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,
137 bool present) {
138 DCHECK(adapter == adapter_.get());
139 if (present) {
140 web_ui()->CallJavascriptFunction(
141 "options.BrowserOptions.showBluetoothSettings");
143 // Update the checkbox and visibility based on the powered state of the
144 // new adapter.
145 AdapterPoweredChanged(adapter_.get(), adapter_->IsPowered());
146 } else {
147 web_ui()->CallJavascriptFunction(
148 "options.BrowserOptions.hideBluetoothSettings");
152 void BluetoothOptionsHandler::AdapterPoweredChanged(BluetoothAdapter* adapter,
153 bool powered) {
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();
200 std::string address;
201 std::string command;
202 args->GetString(kUpdateDeviceAddressIndex, &address);
203 args->GetString(kUpdateDeviceCommandIndex, &command);
204 if (size > kUpdateDevicePasskeyIndex) {
205 // Passkey confirmation as part of the pairing process.
206 std::string passkey;
207 args->GetString(kUpdateDevicePasskeyIndex, &passkey);
208 DVLOG(1) << "UpdateDeviceCallback: " << address << ": " << command
209 << " [" << passkey << "]";
210 } else {
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());
241 if (params) {
242 js_properties.MergeDictionary(params);
244 web_ui()->CallJavascriptFunction(
245 "options.BrowserOptions.addBluetoothDevice",
246 js_properties);
249 void BluetoothOptionsHandler::RequestConfirmation(
250 const BluetoothDevice* device,
251 int passkey) {
252 DictionaryValue params;
253 params.SetString("pairing", "bluetoothConfirmPasskey");
254 params.SetInteger("passkey", passkey);
255 SendDeviceNotification(device, &params);
258 void BluetoothOptionsHandler::DisplayPasskey(
259 const BluetoothDevice* device,
260 int passkey,
261 int entered) {
262 DictionaryValue params;
263 params.SetString("pairing", "bluetoothRemotePasskey");
264 params.SetInteger("passkey", passkey);
265 params.SetInteger("entered", entered);
266 SendDeviceNotification(device, &params);
269 void BluetoothOptionsHandler::RequestPasskey(
270 const BluetoothDevice* device) {
271 DictionaryValue params;
272 params.SetString("pairing", "bluetoothEnterPasskey");
273 SendDeviceNotification(device, &params);
276 void BluetoothOptionsHandler::ReportError(
277 const BluetoothDevice* device,
278 ConnectionError error) {
279 std::string errorCode;
280 switch (error) {
281 case DEVICE_NOT_FOUND:
282 errorCode = "bluetoothErrorNoDevice";
283 break;
284 case INCORRECT_PIN:
285 errorCode = "bluetoothErrorIncorrectPin";
286 break;
287 case CONNECTION_TIMEOUT:
288 errorCode = "bluetoothErrorTimeout";
289 break;
290 case CONNECTION_REJECTED:
291 errorCode = "bluetoothErrorConnectionFailed";
292 break;
294 DictionaryValue params;
295 params.SetString("pairing", errorCode);
296 SendDeviceNotification(device, &params);
299 void BluetoothOptionsHandler::DeviceAdded(BluetoothAdapter* adapter,
300 BluetoothDevice* device) {
301 DCHECK(adapter == adapter_.get());
302 DCHECK(device);
303 SendDeviceNotification(device, NULL);
306 void BluetoothOptionsHandler::DeviceChanged(BluetoothAdapter* adapter,
307 BluetoothDevice* device) {
308 DCHECK(adapter == adapter_.get());
309 DCHECK(device);
310 SendDeviceNotification(device, NULL);
313 void BluetoothOptionsHandler::DeviceRemoved(BluetoothAdapter* adapter,
314 BluetoothDevice* device) {
315 DCHECK(adapter == adapter_.get());
316 DCHECK(device);
318 base::StringValue address(device->address());
319 web_ui()->CallJavascriptFunction(
320 "options.BrowserOptions.removeBluetoothDevice",
321 address);
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