OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" | 5 #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string16.h" | 9 #include "base/string16.h" |
| 10 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
11 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" |
| 14 #include "chrome/browser/chromeos/dbus/bluetooth_adapter_client.h" |
| 15 #include "chrome/browser/chromeos/dbus/bluetooth_agent_service_provider.h" |
12 #include "chrome/browser/chromeos/dbus/bluetooth_device_client.h" | 16 #include "chrome/browser/chromeos/dbus/bluetooth_device_client.h" |
13 #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" | 17 #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" |
| 18 #include "dbus/bus.h" |
14 #include "dbus/object_path.h" | 19 #include "dbus/object_path.h" |
15 #include "grit/generated_resources.h" | 20 #include "grit/generated_resources.h" |
| 21 #include "third_party/cros_system_api/dbus/service_constants.h" |
16 #include "ui/base/l10n/l10n_util.h" | 22 #include "ui/base/l10n/l10n_util.h" |
17 | 23 |
18 namespace chromeos { | 24 namespace chromeos { |
19 | 25 |
20 BluetoothDevice::BluetoothDevice() : bluetooth_class_(0), | 26 BluetoothDevice::BluetoothDevice(BluetoothAdapter* adapter) |
21 paired_(false), | 27 : weak_ptr_factory_(this), |
22 connected_(false) { | 28 adapter_(adapter), |
| 29 bluetooth_class_(0), |
| 30 paired_(false), |
| 31 connected_(false), |
| 32 pairing_delegate_(NULL) { |
23 } | 33 } |
24 | 34 |
25 BluetoothDevice::~BluetoothDevice() { | 35 BluetoothDevice::~BluetoothDevice() { |
26 } | 36 } |
27 | 37 |
28 void BluetoothDevice::SetObjectPath(const dbus::ObjectPath& object_path) { | 38 void BluetoothDevice::SetObjectPath(const dbus::ObjectPath& object_path) { |
29 DCHECK(object_path_ == dbus::ObjectPath("")); | 39 DCHECK(object_path_ == dbus::ObjectPath("")); |
30 object_path_ = object_path; | 40 object_path_ = object_path; |
31 } | 41 } |
32 | 42 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 | 153 |
144 bool BluetoothDevice::WasDiscovered() const { | 154 bool BluetoothDevice::WasDiscovered() const { |
145 return object_path_.value().empty(); | 155 return object_path_.value().empty(); |
146 } | 156 } |
147 | 157 |
148 bool BluetoothDevice::IsConnected() const { | 158 bool BluetoothDevice::IsConnected() const { |
149 // TODO(keybuk): examine protocol-specific connected state, such as Input | 159 // TODO(keybuk): examine protocol-specific connected state, such as Input |
150 return connected_; | 160 return connected_; |
151 } | 161 } |
152 | 162 |
| 163 void BluetoothDevice::Connect(ErrorCallback error_callback) { |
| 164 DBusThreadManager::Get()->GetBluetoothAdapterClient()-> |
| 165 CreateDevice(adapter_->object_path_, |
| 166 address_, |
| 167 base::Bind(&BluetoothDevice::ConnectCallback, |
| 168 weak_ptr_factory_.GetWeakPtr(), |
| 169 error_callback)); |
| 170 } |
| 171 |
| 172 void BluetoothDevice::PairAndConnect(PairingDelegate* pairing_delegate, |
| 173 ErrorCallback error_callback) { |
| 174 DCHECK(!pairing_delegate_); |
| 175 pairing_delegate_ = pairing_delegate; |
| 176 |
| 177 // The agent path is relatively meaningless, we use the device address |
| 178 // to generate it as we only support one pairing attempt at a time for |
| 179 // a given bluetooth device. |
| 180 DCHECK(agent_.get() == NULL); |
| 181 |
| 182 std::string agent_path_basename; |
| 183 ReplaceChars(address_, ":", "_", &agent_path_basename); |
| 184 dbus::ObjectPath agent_path("/org/chromium/bluetooth_agent/" + |
| 185 agent_path_basename); |
| 186 |
| 187 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); |
| 188 agent_.reset(BluetoothAgentServiceProvider::Create(system_bus, |
| 189 agent_path, |
| 190 this)); |
| 191 |
| 192 DVLOG(1) << "Pairing: " << address_; |
| 193 DBusThreadManager::Get()->GetBluetoothAdapterClient()-> |
| 194 CreatePairedDevice(adapter_->object_path_, |
| 195 address_, |
| 196 agent_path, |
| 197 bluetooth_agent::kDisplayYesNoCapability, |
| 198 base::Bind(&BluetoothDevice::ConnectCallback, |
| 199 weak_ptr_factory_.GetWeakPtr(), |
| 200 error_callback)); |
| 201 } |
| 202 |
| 203 void BluetoothDevice::ConnectCallback(ErrorCallback error_callback, |
| 204 const dbus::ObjectPath& device_path, |
| 205 bool success) { |
| 206 if (success) { |
| 207 DVLOG(1) << "Connection successful: " << device_path.value(); |
| 208 if (object_path_.value().empty()) { |
| 209 object_path_ = device_path; |
| 210 } else { |
| 211 LOG_IF(WARNING, object_path_ != device_path) |
| 212 << "Conflicting device paths for objects, result gave: " |
| 213 << device_path.value() << " but signal gave: " |
| 214 << object_path_.value(); |
| 215 } |
| 216 } else { |
| 217 LOG(WARNING) << "Connection failed: " << address_; |
| 218 error_callback.Run(); |
| 219 } |
| 220 } |
| 221 |
| 222 void BluetoothDevice::SetPinCode(const std::string& pincode) { |
| 223 if (!agent_.get() || pincode_callback_.is_null()) |
| 224 return; |
| 225 |
| 226 pincode_callback_.Run(SUCCESS, pincode); |
| 227 pincode_callback_.Reset(); |
| 228 } |
| 229 |
| 230 void BluetoothDevice::SetPasskey(uint32 passkey) { |
| 231 if (!agent_.get() || passkey_callback_.is_null()) |
| 232 return; |
| 233 |
| 234 passkey_callback_.Run(SUCCESS, passkey); |
| 235 passkey_callback_.Reset(); |
| 236 } |
| 237 |
| 238 void BluetoothDevice::ConfirmPairing() { |
| 239 if (!agent_.get() || confirmation_callback_.is_null()) |
| 240 return; |
| 241 |
| 242 confirmation_callback_.Run(SUCCESS); |
| 243 confirmation_callback_.Reset(); |
| 244 } |
| 245 |
| 246 void BluetoothDevice::RejectPairing() { |
| 247 if (!agent_.get()) |
| 248 return; |
| 249 |
| 250 if (!pincode_callback_.is_null()) { |
| 251 pincode_callback_.Run(REJECTED, ""); |
| 252 pincode_callback_.Reset(); |
| 253 } |
| 254 if (!passkey_callback_.is_null()) { |
| 255 passkey_callback_.Run(REJECTED, 0); |
| 256 passkey_callback_.Reset(); |
| 257 } |
| 258 if (!confirmation_callback_.is_null()) { |
| 259 confirmation_callback_.Run(REJECTED); |
| 260 confirmation_callback_.Reset(); |
| 261 } |
| 262 } |
| 263 |
| 264 void BluetoothDevice::CancelPairing() { |
| 265 if (!agent_.get()) |
| 266 return; |
| 267 |
| 268 if (!pincode_callback_.is_null()) { |
| 269 pincode_callback_.Run(CANCELLED, ""); |
| 270 pincode_callback_.Reset(); |
| 271 } |
| 272 if (!passkey_callback_.is_null()) { |
| 273 passkey_callback_.Run(CANCELLED, 0); |
| 274 passkey_callback_.Reset(); |
| 275 } |
| 276 if (!confirmation_callback_.is_null()) { |
| 277 confirmation_callback_.Run(CANCELLED); |
| 278 confirmation_callback_.Reset(); |
| 279 } |
| 280 } |
| 281 |
| 282 void BluetoothDevice::DisconnectRequested(const dbus::ObjectPath& object_path) { |
| 283 DCHECK(object_path == object_path_); |
| 284 } |
| 285 |
| 286 void BluetoothDevice::Release() { |
| 287 DCHECK(agent_.get()); |
| 288 DVLOG(1) << "Release: " << address_; |
| 289 |
| 290 DCHECK(pairing_delegate_); |
| 291 pairing_delegate_->DismissDisplayOrConfirm(); |
| 292 pairing_delegate_ = NULL; |
| 293 |
| 294 pincode_callback_.Reset(); |
| 295 passkey_callback_.Reset(); |
| 296 confirmation_callback_.Reset(); |
| 297 |
| 298 agent_.reset(); |
| 299 } |
| 300 |
| 301 void BluetoothDevice::RequestPinCode(const dbus::ObjectPath& device_path, |
| 302 const PinCodeCallback& callback) { |
| 303 DCHECK(agent_.get()); |
| 304 DVLOG(1) << "RequestPinCode: " << device_path.value(); |
| 305 |
| 306 DCHECK(pairing_delegate_); |
| 307 DCHECK(pincode_callback_.is_null()); |
| 308 pincode_callback_ = callback; |
| 309 pairing_delegate_->RequestPinCode(this); |
| 310 } |
| 311 |
| 312 void BluetoothDevice::RequestPasskey(const dbus::ObjectPath& device_path, |
| 313 const PasskeyCallback& callback) { |
| 314 DCHECK(agent_.get()); |
| 315 DCHECK(device_path == object_path_); |
| 316 DVLOG(1) << "RequestPasskey: " << device_path.value(); |
| 317 |
| 318 DCHECK(pairing_delegate_); |
| 319 DCHECK(passkey_callback_.is_null()); |
| 320 passkey_callback_ = callback; |
| 321 pairing_delegate_->RequestPasskey(this); |
| 322 } |
| 323 |
| 324 void BluetoothDevice::DisplayPinCode(const dbus::ObjectPath& device_path, |
| 325 const std::string& pincode) { |
| 326 DCHECK(agent_.get()); |
| 327 DCHECK(device_path == object_path_); |
| 328 DVLOG(1) << "DisplayPinCode: " << device_path.value() << " " << pincode; |
| 329 |
| 330 DCHECK(pairing_delegate_); |
| 331 pairing_delegate_->DisplayPinCode(this, pincode); |
| 332 } |
| 333 |
| 334 void BluetoothDevice::DisplayPasskey(const dbus::ObjectPath& device_path, |
| 335 uint32 passkey) { |
| 336 DCHECK(agent_.get()); |
| 337 DCHECK(device_path == object_path_); |
| 338 DVLOG(1) << "DisplayPasskey: " << device_path.value() << " " << passkey; |
| 339 |
| 340 DCHECK(pairing_delegate_); |
| 341 pairing_delegate_->DisplayPasskey(this, passkey); |
| 342 } |
| 343 |
| 344 void BluetoothDevice::RequestConfirmation( |
| 345 const dbus::ObjectPath& device_path, |
| 346 uint32 passkey, |
| 347 const ConfirmationCallback& callback) { |
| 348 DCHECK(agent_.get()); |
| 349 DCHECK(device_path == object_path_); |
| 350 DVLOG(1) << "RequestConfirmation: " << device_path.value() << " " << passkey; |
| 351 |
| 352 DCHECK(pairing_delegate_); |
| 353 DCHECK(confirmation_callback_.is_null()); |
| 354 confirmation_callback_ = callback; |
| 355 pairing_delegate_->ConfirmPasskey(this, passkey); |
| 356 } |
| 357 |
| 358 void BluetoothDevice::Authorize(const dbus::ObjectPath& device_path, |
| 359 const std::string& uuid, |
| 360 const ConfirmationCallback& callback) { |
| 361 DCHECK(agent_.get()); |
| 362 DCHECK(device_path == object_path_); |
| 363 LOG(WARNING) << "Rejected authorization for service: " << uuid |
| 364 << " requested from device: " << device_path.value(); |
| 365 callback.Run(REJECTED); |
| 366 } |
| 367 |
| 368 void BluetoothDevice::ConfirmModeChange(Mode mode, |
| 369 const ConfirmationCallback& callback) { |
| 370 DCHECK(agent_.get()); |
| 371 LOG(WARNING) << "Rejected adapter-level mode change: " << mode |
| 372 << " made on agent for device: " << address_; |
| 373 callback.Run(REJECTED); |
| 374 } |
| 375 |
| 376 void BluetoothDevice::Cancel() { |
| 377 DCHECK(agent_.get()); |
| 378 DVLOG(1) << "Cancel: " << address_; |
| 379 |
| 380 DCHECK(pairing_delegate_); |
| 381 pairing_delegate_->DismissDisplayOrConfirm(); |
| 382 } |
| 383 |
153 | 384 |
154 // static | 385 // static |
155 BluetoothDevice* BluetoothDevice::CreateBound( | 386 BluetoothDevice* BluetoothDevice::CreateBound( |
| 387 BluetoothAdapter* adapter, |
156 const dbus::ObjectPath& object_path, | 388 const dbus::ObjectPath& object_path, |
157 const BluetoothDeviceClient::Properties* properties) { | 389 const BluetoothDeviceClient::Properties* properties) { |
158 BluetoothDevice* device = new BluetoothDevice; | 390 BluetoothDevice* device = new BluetoothDevice(adapter); |
159 device->SetObjectPath(object_path); | 391 device->SetObjectPath(object_path); |
160 device->Update(properties, true); | 392 device->Update(properties, true); |
161 return device; | 393 return device; |
162 } | 394 } |
163 | 395 |
164 // static | 396 // static |
165 BluetoothDevice* BluetoothDevice::CreateUnbound( | 397 BluetoothDevice* BluetoothDevice::CreateUnbound( |
| 398 BluetoothAdapter* adapter, |
166 const BluetoothDeviceClient::Properties* properties) { | 399 const BluetoothDeviceClient::Properties* properties) { |
167 BluetoothDevice* device = new BluetoothDevice; | 400 BluetoothDevice* device = new BluetoothDevice(adapter); |
168 device->Update(properties, false); | 401 device->Update(properties, false); |
169 return device; | 402 return device; |
170 } | 403 } |
171 | 404 |
172 } // namespace chromeos | 405 } // namespace chromeos |
OLD | NEW |