Disable media android perf tests
[chromium-blink-merge.git] / device / bluetooth / bluetooth_adapter_chromeos.cc
blob319a6e99a63348aea5fc79705b9c9605e5d4b981
1 // Copyright 2013 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 "device/bluetooth/bluetooth_adapter_chromeos.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/metrics/histogram.h"
12 #include "base/sys_info.h"
13 #include "chromeos/dbus/bluetooth_adapter_client.h"
14 #include "chromeos/dbus/bluetooth_device_client.h"
15 #include "chromeos/dbus/bluetooth_input_client.h"
16 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "device/bluetooth/bluetooth_device.h"
18 #include "device/bluetooth/bluetooth_device_chromeos.h"
20 using device::BluetoothAdapter;
21 using device::BluetoothDevice;
23 namespace chromeos {
25 BluetoothAdapterChromeOS::BluetoothAdapterChromeOS()
26 : weak_ptr_factory_(this) {
27 DBusThreadManager::Get()->GetBluetoothAdapterClient()->AddObserver(this);
28 DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
29 DBusThreadManager::Get()->GetBluetoothInputClient()->AddObserver(this);
31 std::vector<dbus::ObjectPath> object_paths =
32 DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetAdapters();
34 if (!object_paths.empty()) {
35 VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available.";
36 SetAdapter(object_paths[0]);
40 BluetoothAdapterChromeOS::~BluetoothAdapterChromeOS() {
41 DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this);
42 DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this);
43 DBusThreadManager::Get()->GetBluetoothInputClient()->RemoveObserver(this);
46 void BluetoothAdapterChromeOS::AddObserver(
47 BluetoothAdapter::Observer* observer) {
48 DCHECK(observer);
49 observers_.AddObserver(observer);
52 void BluetoothAdapterChromeOS::RemoveObserver(
53 BluetoothAdapter::Observer* observer) {
54 DCHECK(observer);
55 observers_.RemoveObserver(observer);
58 std::string BluetoothAdapterChromeOS::GetAddress() const {
59 if (!IsPresent())
60 return std::string();
62 BluetoothAdapterClient::Properties* properties =
63 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
64 GetProperties(object_path_);
65 DCHECK(properties);
67 return properties->address.value();
70 std::string BluetoothAdapterChromeOS::GetName() const {
71 if (!IsPresent())
72 return std::string();
74 BluetoothAdapterClient::Properties* properties =
75 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
76 GetProperties(object_path_);
77 DCHECK(properties);
79 return properties->alias.value();
82 bool BluetoothAdapterChromeOS::IsInitialized() const {
83 return true;
86 bool BluetoothAdapterChromeOS::IsPresent() const {
87 return !object_path_.value().empty();
90 bool BluetoothAdapterChromeOS::IsPowered() const {
91 if (!IsPresent())
92 return false;
94 BluetoothAdapterClient::Properties* properties =
95 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
96 GetProperties(object_path_);
98 return properties->powered.value();
101 void BluetoothAdapterChromeOS::SetPowered(
102 bool powered,
103 const base::Closure& callback,
104 const ErrorCallback& error_callback) {
105 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
106 GetProperties(object_path_)->powered.Set(
107 powered,
108 base::Bind(&BluetoothAdapterChromeOS::OnSetPowered,
109 weak_ptr_factory_.GetWeakPtr(),
110 callback,
111 error_callback));
114 bool BluetoothAdapterChromeOS::IsDiscovering() const {
115 if (!IsPresent())
116 return false;
118 BluetoothAdapterClient::Properties* properties =
119 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
120 GetProperties(object_path_);
122 return properties->discovering.value();
125 void BluetoothAdapterChromeOS::StartDiscovering(
126 const base::Closure& callback,
127 const ErrorCallback& error_callback) {
128 // BlueZ counts discovery sessions, and permits multiple sessions for a
129 // single connection, so issue a StartDiscovery() call for every use
130 // within Chromium for the right behavior.
131 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
132 StartDiscovery(
133 object_path_,
134 base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery,
135 weak_ptr_factory_.GetWeakPtr(),
136 callback),
137 base::Bind(&BluetoothAdapterChromeOS::OnStartDiscoveryError,
138 weak_ptr_factory_.GetWeakPtr(),
139 error_callback));
142 void BluetoothAdapterChromeOS::StopDiscovering(
143 const base::Closure& callback,
144 const ErrorCallback& error_callback) {
145 // Inform BlueZ to stop one of our open discovery sessions.
146 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
147 StopDiscovery(
148 object_path_,
149 base::Bind(&BluetoothAdapterChromeOS::OnStopDiscovery,
150 weak_ptr_factory_.GetWeakPtr(),
151 callback),
152 base::Bind(&BluetoothAdapterChromeOS::OnStopDiscoveryError,
153 weak_ptr_factory_.GetWeakPtr(),
154 error_callback));
157 void BluetoothAdapterChromeOS::ReadLocalOutOfBandPairingData(
158 const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback,
159 const ErrorCallback& error_callback) {
160 error_callback.Run();
163 void BluetoothAdapterChromeOS::AdapterAdded(
164 const dbus::ObjectPath& object_path) {
165 // Set the adapter to the newly added adapter only if no adapter is present.
166 if (!IsPresent())
167 SetAdapter(object_path);
170 void BluetoothAdapterChromeOS::AdapterRemoved(
171 const dbus::ObjectPath& object_path) {
172 if (object_path == object_path_)
173 RemoveAdapter();
176 void BluetoothAdapterChromeOS::AdapterPropertyChanged(
177 const dbus::ObjectPath& object_path,
178 const std::string& property_name) {
179 if (object_path != object_path_)
180 return;
182 BluetoothAdapterClient::Properties* properties =
183 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
184 GetProperties(object_path_);
186 if (property_name == properties->powered.name())
187 PoweredChanged(properties->powered.value());
188 else if (property_name == properties->discovering.name())
189 DiscoveringChanged(properties->discovering.value());
192 void BluetoothAdapterChromeOS::DeviceAdded(
193 const dbus::ObjectPath& object_path) {
194 BluetoothDeviceClient::Properties* properties =
195 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
196 GetProperties(object_path);
197 if (properties->adapter.value() != object_path_)
198 return;
200 BluetoothDeviceChromeOS* device_chromeos =
201 new BluetoothDeviceChromeOS(this, object_path);
202 DCHECK(devices_.find(device_chromeos->GetAddress()) == devices_.end());
204 devices_[device_chromeos->GetAddress()] = device_chromeos;
206 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
207 DeviceAdded(this, device_chromeos));
210 void BluetoothAdapterChromeOS::DeviceRemoved(
211 const dbus::ObjectPath& object_path) {
212 for (DevicesMap::iterator iter = devices_.begin();
213 iter != devices_.end(); ++iter) {
214 BluetoothDeviceChromeOS* device_chromeos =
215 static_cast<BluetoothDeviceChromeOS*>(iter->second);
216 if (device_chromeos->object_path() == object_path) {
217 devices_.erase(iter);
219 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
220 DeviceRemoved(this, device_chromeos));
221 delete device_chromeos;
222 return;
227 void BluetoothAdapterChromeOS::DevicePropertyChanged(
228 const dbus::ObjectPath& object_path,
229 const std::string& property_name) {
230 BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path);
231 if (!device_chromeos)
232 return;
234 BluetoothDeviceClient::Properties* properties =
235 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
236 GetProperties(object_path);
238 if (property_name == properties->bluetooth_class.name() ||
239 property_name == properties->address.name() ||
240 property_name == properties->alias.name() ||
241 property_name == properties->paired.name() ||
242 property_name == properties->trusted.name() ||
243 property_name == properties->connected.name() ||
244 property_name == properties->uuids.name())
245 NotifyDeviceChanged(device_chromeos);
247 // UMA connection counting
248 if (property_name == properties->connected.name()) {
249 int count = 0;
251 for (DevicesMap::iterator iter = devices_.begin();
252 iter != devices_.end(); ++iter) {
253 if (iter->second->IsPaired() && iter->second->IsConnected())
254 ++count;
257 UMA_HISTOGRAM_COUNTS_100("Bluetooth.ConnectedDeviceCount", count);
261 void BluetoothAdapterChromeOS::InputPropertyChanged(
262 const dbus::ObjectPath& object_path,
263 const std::string& property_name) {
264 BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path);
265 if (!device_chromeos)
266 return;
268 BluetoothInputClient::Properties* properties =
269 DBusThreadManager::Get()->GetBluetoothInputClient()->
270 GetProperties(object_path);
272 // Properties structure can be removed, which triggers a change in the
273 // BluetoothDevice::IsConnectable() property, as does a change in the
274 // actual reconnect_mode property.
275 if (!properties ||
276 property_name == properties->reconnect_mode.name())
277 NotifyDeviceChanged(device_chromeos);
280 BluetoothDeviceChromeOS*
281 BluetoothAdapterChromeOS::GetDeviceWithPath(
282 const dbus::ObjectPath& object_path) {
283 for (DevicesMap::iterator iter = devices_.begin();
284 iter != devices_.end(); ++iter) {
285 BluetoothDeviceChromeOS* device_chromeos =
286 static_cast<BluetoothDeviceChromeOS*>(iter->second);
287 if (device_chromeos->object_path() == object_path)
288 return device_chromeos;
291 return NULL;
294 void BluetoothAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) {
295 DCHECK(!IsPresent());
296 object_path_ = object_path;
298 VLOG(1) << object_path_.value() << ": using adapter.";
300 SetAdapterName();
302 BluetoothAdapterClient::Properties* properties =
303 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
304 GetProperties(object_path_);
306 PresentChanged(true);
308 if (properties->powered.value())
309 PoweredChanged(true);
310 if (properties->discovering.value())
311 DiscoveringChanged(true);
313 std::vector<dbus::ObjectPath> device_paths =
314 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
315 GetDevicesForAdapter(object_path_);
317 for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin();
318 iter != device_paths.end(); ++iter) {
319 BluetoothDeviceChromeOS* device_chromeos =
320 new BluetoothDeviceChromeOS(this, *iter);
322 devices_[device_chromeos->GetAddress()] = device_chromeos;
324 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
325 DeviceAdded(this, device_chromeos));
329 void BluetoothAdapterChromeOS::SetAdapterName() {
330 std::string board = base::SysInfo::GetLsbReleaseBoard();
331 std::string alias;
332 if (board.substr(0, 6) == "stumpy") {
333 alias = "Chromebox";
334 } else if (board.substr(0, 4) == "link") {
335 alias = "Chromebook Pixel";
336 } else {
337 alias = "Chromebook";
340 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
341 GetProperties(object_path_)->alias.Set(
342 alias,
343 base::Bind(&BluetoothAdapterChromeOS::OnSetAlias,
344 weak_ptr_factory_.GetWeakPtr()));
347 void BluetoothAdapterChromeOS::OnSetAlias(bool success) {
348 LOG_IF(WARNING, !success) << object_path_.value()
349 << ": Failed to set adapter alias";
352 void BluetoothAdapterChromeOS::RemoveAdapter() {
353 DCHECK(IsPresent());
354 VLOG(1) << object_path_.value() << ": adapter removed.";
356 BluetoothAdapterClient::Properties* properties =
357 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
358 GetProperties(object_path_);
360 object_path_ = dbus::ObjectPath("");
362 if (properties->powered.value())
363 PoweredChanged(false);
364 if (properties->discovering.value())
365 DiscoveringChanged(false);
367 // Copy the devices list here and clear the original so that when we
368 // send DeviceRemoved(), GetDevices() returns no devices.
369 DevicesMap devices = devices_;
370 devices_.clear();
372 for (DevicesMap::iterator iter = devices.begin();
373 iter != devices.end(); ++iter) {
374 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
375 DeviceRemoved(this, iter->second));
376 delete iter->second;
379 PresentChanged(false);
382 void BluetoothAdapterChromeOS::PoweredChanged(bool powered) {
383 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
384 AdapterPoweredChanged(this, powered));
387 void BluetoothAdapterChromeOS::DiscoveringChanged(
388 bool discovering) {
389 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
390 AdapterDiscoveringChanged(this, discovering));
393 void BluetoothAdapterChromeOS::PresentChanged(bool present) {
394 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
395 AdapterPresentChanged(this, present));
398 void BluetoothAdapterChromeOS::NotifyDeviceChanged(
399 BluetoothDeviceChromeOS* device) {
400 DCHECK(device->adapter_ == this);
402 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
403 DeviceChanged(this, device));
406 void BluetoothAdapterChromeOS::OnSetPowered(const base::Closure& callback,
407 const ErrorCallback& error_callback,
408 bool success) {
409 if (success)
410 callback.Run();
411 else
412 error_callback.Run();
415 void BluetoothAdapterChromeOS::OnStartDiscovery(const base::Closure& callback) {
416 callback.Run();
419 void BluetoothAdapterChromeOS::OnStartDiscoveryError(
420 const ErrorCallback& error_callback,
421 const std::string& error_name,
422 const std::string& error_message) {
423 LOG(WARNING) << object_path_.value() << ": Failed to start discovery: "
424 << error_name << ": " << error_message;
425 error_callback.Run();
428 void BluetoothAdapterChromeOS::OnStopDiscovery(const base::Closure& callback) {
429 callback.Run();
432 void BluetoothAdapterChromeOS::OnStopDiscoveryError(
433 const ErrorCallback& error_callback,
434 const std::string& error_name,
435 const std::string& error_message) {
436 LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: "
437 << error_name << ": " << error_message;
438 error_callback.Run();
441 } // namespace chromeos