summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/chromeos/dbus/bluetooth_adapter_client.cc468
-rw-r--r--chrome/browser/chromeos/dbus/bluetooth_adapter_client.h73
-rw-r--r--chrome/browser/chromeos/dbus/bluetooth_manager_client.cc194
-rw-r--r--chrome/browser/chromeos/dbus/bluetooth_manager_client.h67
-rw-r--r--chrome/browser/chromeos/dbus/dbus_thread_manager.cc10
-rw-r--r--chrome/browser/chromeos/dbus/dbus_thread_manager.h18
-rw-r--r--chrome/chrome_browser.gypi4
7 files changed, 834 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/dbus/bluetooth_adapter_client.cc b/chrome/browser/chromeos/dbus/bluetooth_adapter_client.cc
new file mode 100644
index 0000000..31ef1dc
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/bluetooth_adapter_client.cc
@@ -0,0 +1,468 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/dbus/bluetooth_adapter_client.h"
+
+#include <map>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "chrome/browser/chromeos/system/runtime_environment.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "dbus/object_proxy.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace {
+
+// Utility function to convert an array of dbus dict_entry objects into a
+// DictionaryValue object.
+//
+// The dict_entry objects must have keys that are strings and values that are
+// simple variants.
+//
+// When converting integral types, we use Integer Value objects to represent
+// uint8, int16, uint16, int32, and uint32 values and Double Value objects to
+// represent int64 and uint64 values.
+//
+// We intend to move this to the chrome dbus library's MessageReader class when
+// it's more fully baked.
+//
+// TODO(vlaviano):
+// - Can we handle integral types better?
+// - Add support for nested complex types.
+// - Write an equivalent function to convert in the opposite direction.
+// - Write unit tests.
+bool PopArrayOfDictEntries(dbus::MessageReader* reader,
+ dbus::Message* message,
+ DictionaryValue* dictionary) {
+ DCHECK(reader);
+ DCHECK(message);
+ DCHECK(dictionary);
+ dbus::MessageReader array_reader(message);
+ if (!reader->PopArray(&array_reader)) {
+ return false;
+ }
+ while (array_reader.HasMoreData()) {
+ dbus::MessageReader dict_entry_reader(message);
+ if (!array_reader.PopDictEntry(&dict_entry_reader)) {
+ return false;
+ }
+ std::string key;
+ if (!dict_entry_reader.PopString(&key)) {
+ return false;
+ }
+ dbus::MessageReader variant_reader(message);
+ if (!dict_entry_reader.PopVariant(&variant_reader)) {
+ return false;
+ }
+ const dbus::Message::DataType type = variant_reader.GetDataType();
+ switch (type) {
+ case dbus::Message::BYTE: {
+ uint8 value = 0;
+ if (!variant_reader.PopByte(&value)) {
+ return false;
+ }
+ dictionary->SetInteger(key, value);
+ break;
+ }
+ case dbus::Message::BOOL: {
+ bool value = false;
+ if (!variant_reader.PopBool(&value)) {
+ return false;
+ }
+ dictionary->SetBoolean(key, value);
+ break;
+ }
+ case dbus::Message::INT16: {
+ int16 value = 0;
+ if (!variant_reader.PopInt16(&value)) {
+ return false;
+ }
+ dictionary->SetInteger(key, value);
+ break;
+ }
+ case dbus::Message::UINT16: {
+ uint16 value = 0;
+ if (!variant_reader.PopUint16(&value)) {
+ return false;
+ }
+ dictionary->SetInteger(key, value);
+ break;
+ }
+ case dbus::Message::INT32: {
+ int32 value = 0;
+ if (!variant_reader.PopInt32(&value)) {
+ return false;
+ }
+ dictionary->SetInteger(key, value);
+ break;
+ }
+ case dbus::Message::UINT32: {
+ uint32 value = 0;
+ if (!variant_reader.PopUint32(&value)) {
+ return false;
+ }
+ dictionary->SetInteger(key, value);
+ break;
+ }
+ case dbus::Message::INT64: {
+ int64 value = 0;
+ if (!variant_reader.PopInt64(&value)) {
+ return false;
+ }
+ dictionary->SetDouble(key, value);
+ break;
+ }
+ case dbus::Message::UINT64: {
+ uint64 value = 0;
+ if (!variant_reader.PopUint64(&value)) {
+ return false;
+ }
+ dictionary->SetDouble(key, value);
+ break;
+ }
+ case dbus::Message::DOUBLE: {
+ double value = 0;
+ if (!variant_reader.PopDouble(&value)) {
+ return false;
+ }
+ dictionary->SetDouble(key, value);
+ break;
+ }
+ case dbus::Message::STRING: {
+ std::string value;
+ if (!variant_reader.PopString(&value)) {
+ return false;
+ }
+ dictionary->SetString(key, value);
+ break;
+ }
+ case dbus::Message::OBJECT_PATH: {
+ std::string value;
+ if (!variant_reader.PopObjectPath(&value)) {
+ return false;
+ }
+ dictionary->SetString(key, value);
+ break;
+ }
+ case dbus::Message::ARRAY: {
+ // Not yet supported.
+ return false;
+ }
+ case dbus::Message::STRUCT: {
+ // Not yet supported.
+ return false;
+ }
+ case dbus::Message::DICT_ENTRY: {
+ // Not yet supported.
+ return false;
+ }
+ case dbus::Message::VARIANT: {
+ // Not yet supported.
+ return false;
+ }
+ default:
+ LOG(FATAL) << "Unknown type: " << type;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
+namespace chromeos {
+
+// The BluetoothAdapterClient implementation used in production.
+class BluetoothAdapterClientImpl: public BluetoothAdapterClient {
+ public:
+ explicit BluetoothAdapterClientImpl(dbus::Bus* bus)
+ : weak_ptr_factory_(this),
+ bus_(bus) {
+ VLOG(1) << "Creating BluetoothAdapterClientImpl";
+ }
+
+ virtual ~BluetoothAdapterClientImpl() {
+ }
+
+ // BluetoothAdapterClient override.
+ virtual void AddObserver(Observer* observer, const std::string& object_path) {
+ VLOG(1) << "AddObserver: " << object_path;
+ DCHECK(observer);
+ observers_.AddObserver(observer);
+ AddObjectProxyForPath(object_path);
+ }
+
+ // BluetoothAdapterClient override.
+ virtual void RemoveObserver(Observer* observer,
+ const std::string& object_path) {
+ VLOG(1) << "RemoveObserver: " << object_path;
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
+ RemoveObjectProxyForPath(object_path);
+ }
+
+ // BluetoothAdapterClient override.
+ virtual void StartDiscovery(const std::string& object_path) {
+ VLOG(1) << "StartDiscovery: " << object_path;
+
+ dbus::MethodCall method_call(
+ bluetooth_adapter::kBluetoothAdapterInterface,
+ bluetooth_adapter::kStartDiscovery);
+
+ ProxyMap::iterator it = proxy_map_.find(object_path);
+ if (it == proxy_map_.end()) {
+ LOG(ERROR) << "Couldn't find proxy for object path " << object_path;
+ return;
+ }
+ dbus::ObjectProxy* adapter_proxy = it->second;
+
+ adapter_proxy->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&BluetoothAdapterClientImpl::OnStartDiscovery,
+ weak_ptr_factory_.GetWeakPtr(), object_path));
+ }
+
+ // BluetoothAdapterClient override.
+ virtual void StopDiscovery(const std::string& object_path) {
+ VLOG(1) << "StopDiscovery: " << object_path;
+
+ dbus::MethodCall method_call(
+ bluetooth_adapter::kBluetoothAdapterInterface,
+ bluetooth_adapter::kStopDiscovery);
+
+ ProxyMap::iterator it = proxy_map_.find(object_path);
+ if (it == proxy_map_.end()) {
+ LOG(ERROR) << "Couldn't find proxy for object path " << object_path;
+ return;
+ }
+ dbus::ObjectProxy* adapter_proxy = it->second;
+
+ adapter_proxy->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&BluetoothAdapterClientImpl::OnStopDiscovery,
+ weak_ptr_factory_.GetWeakPtr(), object_path));
+ }
+
+ private:
+ // Gets a dbus object proxy for an adapter with dbus object path |object_path|
+ // and stores it in our |proxy_map_| map.
+ void AddObjectProxyForPath(const std::string& object_path) {
+ VLOG(1) << "AddObjectProxyForPath: " << object_path;
+
+ DCHECK(bus_);
+ dbus::ObjectProxy* adapter_proxy = bus_->GetObjectProxy(
+ bluetooth_adapter::kBluetoothAdapterServiceName, object_path);
+
+ proxy_map_[object_path] = adapter_proxy;
+
+ adapter_proxy->ConnectToSignal(
+ bluetooth_adapter::kBluetoothAdapterInterface,
+ bluetooth_adapter::kPropertyChangedSignal,
+ base::Bind(&BluetoothAdapterClientImpl::PropertyChangedReceived,
+ weak_ptr_factory_.GetWeakPtr(), object_path),
+ base::Bind(&BluetoothAdapterClientImpl::PropertyChangedConnected,
+ weak_ptr_factory_.GetWeakPtr(), object_path));
+
+ adapter_proxy->ConnectToSignal(
+ bluetooth_adapter::kBluetoothAdapterInterface,
+ bluetooth_adapter::kDeviceFoundSignal,
+ base::Bind(&BluetoothAdapterClientImpl::DeviceFoundReceived,
+ weak_ptr_factory_.GetWeakPtr(), object_path),
+ base::Bind(&BluetoothAdapterClientImpl::DeviceFoundConnected,
+ weak_ptr_factory_.GetWeakPtr(), object_path));
+
+ adapter_proxy->ConnectToSignal(
+ bluetooth_adapter::kBluetoothAdapterInterface,
+ bluetooth_adapter::kDeviceDisappearedSignal,
+ base::Bind(&BluetoothAdapterClientImpl::DeviceDisappearedReceived,
+ weak_ptr_factory_.GetWeakPtr(), object_path),
+ base::Bind(&BluetoothAdapterClientImpl::DeviceDisappearedConnected,
+ weak_ptr_factory_.GetWeakPtr(), object_path));
+ }
+
+ // Removes the dbus object proxy for the adapter with dbus object path
+ // |object_path| from our |proxy_map_| map.
+ void RemoveObjectProxyForPath(const std::string& object_path) {
+ VLOG(1) << "RemoveObjectProxyForPath: " << object_path;
+ proxy_map_.erase(object_path);
+ }
+
+ // Called by dbus:: when a PropertyChanged signal is received.
+ void PropertyChangedReceived(const std::string& object_path,
+ dbus::Signal* signal) {
+ DCHECK(signal);
+ dbus::MessageReader reader(signal);
+ std::string property_name;
+ if (!reader.PopString(&property_name)) {
+ LOG(ERROR) << object_path
+ << ": PropertyChanged signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+
+ if (property_name != bluetooth_adapter::kDiscoveringProperty) {
+ VLOG(1) << object_path << ": PropertyChanged: " << property_name;
+ // We don't care.
+ return;
+ }
+
+ bool discovering = false;
+ if (!reader.PopVariantOfBool(&discovering)) {
+ LOG(ERROR) << object_path
+ << ": PropertyChanged signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+ VLOG(1) << object_path << ": PropertyChanged: Discovering = "
+ << discovering;
+
+ FOR_EACH_OBSERVER(Observer, observers_,
+ DiscoveringPropertyChanged(object_path, discovering));
+ }
+
+ // Called by dbus:: when the PropertyChanged signal is initially connected.
+ void PropertyChangedConnected(const std::string& object_path,
+ const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ LOG_IF(WARNING, !success) << object_path
+ << ": Failed to connect to PropertyChanged signal.";
+ }
+
+ // Called by dbus:: when a DeviceFound signal is received.
+ void DeviceFoundReceived(const std::string& object_path,
+ dbus::Signal* signal) {
+ DCHECK(signal);
+ dbus::MessageReader reader(signal);
+ std::string address;
+ if (!reader.PopString(&address)) {
+ LOG(ERROR) << object_path
+ << ": DeviceFound signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+ VLOG(1) << object_path << ": Device found: " << address;
+
+ DictionaryValue device_properties;
+ if (!PopArrayOfDictEntries(&reader, signal, &device_properties)) {
+ LOG(ERROR) << object_path
+ << ": DeviceFound signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+
+ FOR_EACH_OBSERVER(Observer, observers_, DeviceFound(object_path, address,
+ device_properties));
+ }
+
+ // Called by dbus:: when the DeviceFound signal is initially connected.
+ void DeviceFoundConnected(const std::string& object_path,
+ const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ LOG_IF(WARNING, !success) << object_path
+ << ": Failed to connect to DeviceFound signal.";
+ }
+
+ // Called by dbus:: when a DeviceDisappeared signal is received.
+ void DeviceDisappearedReceived(const std::string& object_path,
+ dbus::Signal* signal) {
+ DCHECK(signal);
+ dbus::MessageReader reader(signal);
+ std::string address;
+ if (!reader.PopString(&address)) {
+ LOG(ERROR) << object_path
+ << ": DeviceDisappeared signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+ VLOG(1) << object_path << ": Device disappeared: " << address;
+ FOR_EACH_OBSERVER(Observer, observers_, DeviceDisappeared(object_path,
+ address));
+ }
+
+ // Called by dbus:: when the DeviceDisappeared signal is initially connected.
+ void DeviceDisappearedConnected(const std::string& object_path,
+ const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ LOG_IF(WARNING, !success) << object_path
+ << ": Failed to connect to DeviceDisappeared signal.";
+ }
+
+ // Called when a response for StartDiscovery() is received.
+ void OnStartDiscovery(const std::string& object_path,
+ dbus::Response* response) {
+ VLOG(1) << "OnStartDiscovery: " << object_path;
+ LOG_IF(WARNING, !response) << object_path << ": OnStartDiscovery: failed.";
+ }
+
+ // Called when a response for StopDiscovery() is received.
+ void OnStopDiscovery(const std::string& object_path,
+ dbus::Response* response) {
+ VLOG(1) << "OnStopDiscovery: " << object_path;
+ LOG_IF(WARNING, !response) << object_path << ": OnStopDiscovery: failed.";
+ }
+
+ // Weak pointer factory for generating 'this' pointers that might live longer
+ // than we do.
+ base::WeakPtrFactory<BluetoothAdapterClientImpl> weak_ptr_factory_;
+
+ dbus::Bus* bus_;
+
+ // We maintain a collection of dbus object proxies, one for each adapter.
+ typedef std::map<const std::string, dbus::ObjectProxy*> ProxyMap;
+ ProxyMap proxy_map_;
+
+ // List of observers interested in event notifications from us.
+ ObserverList<Observer> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl);
+};
+
+// The BluetoothAdapterClient implementation used on Linux desktop, which does
+// nothing.
+class BluetoothAdapterClientStubImpl : public BluetoothAdapterClient {
+ public:
+ // BluetoothAdapterClient override.
+ virtual void AddObserver(Observer* observer, const std::string& object_path) {
+ VLOG(1) << "AddObserver: " << object_path;
+ }
+
+ // BluetoothAdapterClient override.
+ virtual void RemoveObserver(Observer* observer,
+ const std::string& object_path) {
+ VLOG(1) << "RemoveObserver: " << object_path;
+ }
+
+ // BluetoothAdapterClient override.
+ virtual void StartDiscovery(const std::string& object_path) {
+ VLOG(1) << "StartDiscovery: " << object_path;
+ }
+
+ // BluetoothAdapterClient override.
+ virtual void StopDiscovery(const std::string& object_path) {
+ VLOG(1) << "StopDiscovery: " << object_path;
+ }
+};
+
+BluetoothAdapterClient::BluetoothAdapterClient() {
+}
+
+BluetoothAdapterClient::~BluetoothAdapterClient() {
+}
+
+BluetoothAdapterClient* BluetoothAdapterClient::Create(dbus::Bus* bus) {
+ if (system::runtime_environment::IsRunningOnChromeOS()) {
+ return new BluetoothAdapterClientImpl(bus);
+ } else {
+ return new BluetoothAdapterClientStubImpl();
+ }
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/dbus/bluetooth_adapter_client.h b/chrome/browser/chromeos/dbus/bluetooth_adapter_client.h
new file mode 100644
index 0000000..73aaee2
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/bluetooth_adapter_client.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
+#define CHROME_BROWSER_CHROMEOS_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
+#pragma once
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/observer_list.h"
+#include "base/values.h"
+
+namespace dbus {
+class Bus;
+} // namespace dbus
+
+namespace chromeos {
+
+// BluetoothAdapterClient is used to communicate with a bluetooth Adapter
+// interface.
+class BluetoothAdapterClient {
+ public:
+ // Interface for observing changes from a local bluetooth adapter.
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called when the adapter's Discovering property changes.
+ virtual void DiscoveringPropertyChanged(const std::string& object_path,
+ bool discovering) {}
+
+ // Called when a new remote device has been discovered.
+ // |device_properties| should be copied if needed.
+ virtual void DeviceFound(const std::string& object_path,
+ const std::string& address,
+ const DictionaryValue& device_properties) {}
+
+ // Called when a previously discovered device is no longer visible.
+ virtual void DeviceDisappeared(const std::string& object_path,
+ const std::string& address) {}
+ };
+
+ virtual ~BluetoothAdapterClient();
+
+ // Adds and removes observers for events on the adapter with object path
+ // |object_path|.
+ virtual void AddObserver(Observer* observer,
+ const std::string& object_path) = 0;
+ virtual void RemoveObserver(Observer* observer,
+ const std::string& object_path) = 0;
+
+ // Starts a device discovery on the adapter with object path |object_path|.
+ virtual void StartDiscovery(const std::string& object_path) = 0;
+
+ // Cancels any previous device discovery on the adapter with object path
+ // |object_path|.
+ virtual void StopDiscovery(const std::string& object_path) = 0;
+
+ // Creates the instance.
+ static BluetoothAdapterClient* Create(dbus::Bus* bus);
+
+ protected:
+ BluetoothAdapterClient();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
diff --git a/chrome/browser/chromeos/dbus/bluetooth_manager_client.cc b/chrome/browser/chromeos/dbus/bluetooth_manager_client.cc
new file mode 100644
index 0000000..9419e3b
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/bluetooth_manager_client.cc
@@ -0,0 +1,194 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/dbus/bluetooth_manager_client.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "chrome/browser/chromeos/system/runtime_environment.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "dbus/object_proxy.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+// The BluetoothManagerClient implementation used in production.
+class BluetoothManagerClientImpl : public BluetoothManagerClient {
+ public:
+ explicit BluetoothManagerClientImpl(dbus::Bus* bus)
+ : weak_ptr_factory_(this),
+ bluetooth_manager_proxy_(NULL) {
+ VLOG(1) << "Creating BluetoothManagerClientImpl";
+
+ DCHECK(bus);
+
+ bluetooth_manager_proxy_ = bus->GetObjectProxy(
+ bluetooth_manager::kBluetoothManagerServiceName,
+ bluetooth_manager::kBluetoothManagerServicePath);
+
+ bluetooth_manager_proxy_->ConnectToSignal(
+ bluetooth_manager::kBluetoothManagerInterface,
+ bluetooth_manager::kAdapterRemovedSignal,
+ base::Bind(&BluetoothManagerClientImpl::AdapterRemovedReceived,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&BluetoothManagerClientImpl::AdapterRemovedConnected,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ bluetooth_manager_proxy_->ConnectToSignal(
+ bluetooth_manager::kBluetoothManagerInterface,
+ bluetooth_manager::kDefaultAdapterChangedSignal,
+ base::Bind(&BluetoothManagerClientImpl::DefaultAdapterChangedReceived,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&BluetoothManagerClientImpl::DefaultAdapterChangedConnected,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+
+ virtual ~BluetoothManagerClientImpl() {
+ }
+
+ // BluetoothManagerClient override.
+ virtual void AddObserver(Observer* observer) {
+ VLOG(1) << "AddObserver";
+ DCHECK(observer);
+ observers_.AddObserver(observer);
+ }
+
+ // BluetoothManagerClient override.
+ virtual void RemoveObserver(Observer* observer) {
+ VLOG(1) << "RemoveObserver";
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
+ }
+
+ // BluetoothManagerClient override.
+ virtual void DefaultAdapter(const DefaultAdapterCallback& callback) {
+ LOG(INFO) << "DefaultAdapter";
+
+ dbus::MethodCall method_call(
+ bluetooth_manager::kBluetoothManagerInterface,
+ bluetooth_manager::kDefaultAdapter);
+
+ DCHECK(bluetooth_manager_proxy_);
+ bluetooth_manager_proxy_->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&BluetoothManagerClientImpl::OnDefaultAdapter,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+ }
+
+ private:
+ // Called by dbus:: when an AdapterRemoved signal is received.
+ void AdapterRemovedReceived(dbus::Signal* signal) {
+ DCHECK(signal);
+ dbus::MessageReader reader(signal);
+ std::string adapter;
+ if (!reader.PopObjectPath(&adapter)) {
+ LOG(ERROR) << "AdapterRemoved signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+ VLOG(1) << "Adapter removed: " << adapter;
+ FOR_EACH_OBSERVER(Observer, observers_, AdapterRemoved(adapter));
+ }
+
+ // Called by dbus:: when the AdapterRemoved signal is initially connected.
+ void AdapterRemovedConnected(const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ LOG_IF(WARNING, !success) << "Failed to connect to AdapterRemoved signal.";
+ }
+
+ // Called by dbus:: when a DefaultAdapterChanged signal is received.
+ void DefaultAdapterChangedReceived(dbus::Signal* signal) {
+ DCHECK(signal);
+ dbus::MessageReader reader(signal);
+ std::string adapter;
+ if (!reader.PopObjectPath(&adapter)) {
+ LOG(ERROR) << "DefaultAdapterChanged signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+ VLOG(1) << "Default adapter changed: " << adapter;
+ FOR_EACH_OBSERVER(Observer, observers_, DefaultAdapterChanged(adapter));
+ }
+
+ // Called by dbus:: when the DefaultAdapterChanged signal is initially
+ // connected.
+ void DefaultAdapterChangedConnected(const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ LOG_IF(WARNING, !success)
+ << "Failed to connect to DefaultAdapterChanged signal.";
+ }
+
+ // Called when a response for DefaultAdapter() is received.
+ void OnDefaultAdapter(const DefaultAdapterCallback& callback,
+ dbus::Response* response) {
+ // Parse response.
+ bool success = false;
+ std::string adapter;
+ if (response != NULL) {
+ dbus::MessageReader reader(response);
+ if (!reader.PopObjectPath(&adapter)) {
+ LOG(ERROR) << "DefaultAdapter response has incorrect parameters: "
+ << response->ToString();
+ } else {
+ success = true;
+ LOG(INFO) << "OnDefaultAdapter: " << adapter;
+ }
+ } else {
+ LOG(ERROR) << "Failed to get default adapter.";
+ }
+
+ // Notify client.
+ callback.Run(adapter, success);
+ }
+
+ // Weak pointer factory for generating 'this' pointers that might live longer
+ // than we do.
+ base::WeakPtrFactory<BluetoothManagerClientImpl> weak_ptr_factory_;
+
+ // D-Bus proxy for BlueZ Manager interface.
+ dbus::ObjectProxy* bluetooth_manager_proxy_;
+
+ // List of observers interested in event notifications from us.
+ ObserverList<Observer> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(BluetoothManagerClientImpl);
+};
+
+// The BluetoothManagerClient implementation used on Linux desktop, which does
+// nothing.
+class BluetoothManagerClientStubImpl : public BluetoothManagerClient {
+ public:
+ // BluetoothManagerClient override.
+ virtual void AddObserver(Observer* observer) {
+ }
+
+ // BluetoothManagerClient override.
+ virtual void RemoveObserver(Observer* observer) {
+ }
+
+ // BluetoothManagerClient override.
+ virtual void DefaultAdapter(const DefaultAdapterCallback& callback) {
+ VLOG(1) << "Requested default adapter.";
+ }
+};
+
+BluetoothManagerClient::BluetoothManagerClient() {
+}
+
+BluetoothManagerClient::~BluetoothManagerClient() {
+}
+
+BluetoothManagerClient* BluetoothManagerClient::Create(dbus::Bus* bus) {
+ if (system::runtime_environment::IsRunningOnChromeOS()) {
+ return new BluetoothManagerClientImpl(bus);
+ } else {
+ return new BluetoothManagerClientStubImpl();
+ }
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/dbus/bluetooth_manager_client.h b/chrome/browser/chromeos/dbus/bluetooth_manager_client.h
new file mode 100644
index 0000000..5060043
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/bluetooth_manager_client.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DBUS_BLUETOOTH_MANAGER_CLIENT_H_
+#define CHROME_BROWSER_CHROMEOS_DBUS_BLUETOOTH_MANAGER_CLIENT_H_
+#pragma once
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/observer_list.h"
+
+namespace dbus {
+class Bus;
+} // namespace dbus
+
+namespace chromeos {
+
+// BluetoothManagerClient is used to communicate with the bluetooth
+// daemon's Manager interface.
+class BluetoothManagerClient {
+ public:
+ // Interface for observing changes from the bluetooth manager.
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called when a local bluetooth adapter is removed.
+ // |adapter| is the dbus object path of the adapter.
+ virtual void AdapterRemoved(const std::string& adapter) {}
+
+ // Called when the default local bluetooth adapter changes.
+ // |adapter| is the dbus object path of the new default adapter.
+ // Not called if all adapters are removed.
+ virtual void DefaultAdapterChanged(const std::string& adapter) {}
+ };
+
+ virtual ~BluetoothManagerClient();
+
+ // Adds and removes the observer.
+ virtual void AddObserver(Observer* observer) = 0;
+ virtual void RemoveObserver(Observer* observer) = 0;
+
+ // The DefaultAdapterCallback receives two arguments:
+ // std::string adapter - the unique identifier of the default adapter
+ // bool success - whether or not the request succeeded
+ typedef base::Callback<void(std::string, bool)> DefaultAdapterCallback;
+
+ // Retrieves the dbus object path for the default adapter.
+ // The default adapter is the preferred local bluetooth interface when a
+ // client does not specify a particular interface.
+ virtual void DefaultAdapter(const DefaultAdapterCallback& callback) = 0;
+
+ // Creates the instance.
+ static BluetoothManagerClient* Create(dbus::Bus* bus);
+
+ protected:
+ BluetoothManagerClient();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BluetoothManagerClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_DBUS_BLUETOOTH_MANAGER_CLIENT_H_
diff --git a/chrome/browser/chromeos/dbus/dbus_thread_manager.cc b/chrome/browser/chromeos/dbus/dbus_thread_manager.cc
index 30486c9..e2e0ec6 100644
--- a/chrome/browser/chromeos/dbus/dbus_thread_manager.cc
+++ b/chrome/browser/chromeos/dbus/dbus_thread_manager.cc
@@ -6,6 +6,8 @@
#include "base/command_line.h"
#include "base/threading/thread.h"
+#include "chrome/browser/chromeos/dbus/bluetooth_adapter_client.h"
+#include "chrome/browser/chromeos/dbus/bluetooth_manager_client.h"
#include "chrome/browser/chromeos/dbus/cros_dbus_service.h"
#include "chrome/browser/chromeos/dbus/session_manager_client.h"
#include "chrome/browser/chromeos/dbus/power_manager_client.h"
@@ -44,6 +46,14 @@ DBusThreadManager::DBusThreadManager() {
sensors_source_->Init(system_bus_.get());
}
+ // Create bluetooth clients if bluetooth is enabled.
+ if (command_line.HasSwitch(switches::kEnableBluetooth)) {
+ bluetooth_manager_client_.reset(BluetoothManagerClient::Create(
+ system_bus_.get()));
+ bluetooth_adapter_client_.reset(BluetoothAdapterClient::Create(
+ system_bus_.get()));
+ }
+
// Create the power manager client.
power_manager_client_.reset(PowerManagerClient::Create(system_bus_.get()));
// Create the session manager client.
diff --git a/chrome/browser/chromeos/dbus/dbus_thread_manager.h b/chrome/browser/chromeos/dbus/dbus_thread_manager.h
index 3225403..f9ead09 100644
--- a/chrome/browser/chromeos/dbus/dbus_thread_manager.h
+++ b/chrome/browser/chromeos/dbus/dbus_thread_manager.h
@@ -19,6 +19,8 @@ class Bus;
namespace chromeos {
+class BluetoothAdapterClient;
+class BluetoothManagerClient;
class CrosDBusService;
class PowerManagerClient;
class SessionManagerClient;
@@ -56,6 +58,20 @@ class DBusThreadManager {
// Gets the global instance. Initialize() must be called first.
static DBusThreadManager* Get();
+ // Returns the bluetooth manager client, owned by DBusThreadManager.
+ // Do not cache this pointer and use it after DBusThreadManager is shut
+ // down.
+ BluetoothManagerClient* bluetooth_manager_client() {
+ return bluetooth_manager_client_.get();
+ }
+
+ // Returns the bluetooth adapter client, owned by DBusThreadManager.
+ // Do not cache this pointer and use it after DBusThreadManager is shut
+ // down.
+ BluetoothAdapterClient* bluetooth_adapter_client() {
+ return bluetooth_adapter_client_.get();
+ }
+
// Returns the power manager client, owned by DBusThreadManager.
// See also comments at session_manager_client().
PowerManagerClient* power_manager_client() {
@@ -89,6 +105,8 @@ class DBusThreadManager {
scoped_refptr<dbus::Bus> system_bus_;
CrosDBusService* cros_dbus_service_;
scoped_ptr<SensorsSource> sensors_source_;
+ scoped_ptr<BluetoothManagerClient> bluetooth_manager_client_;
+ scoped_ptr<BluetoothAdapterClient> bluetooth_adapter_client_;
scoped_ptr<PowerManagerClient> power_manager_client_;
scoped_ptr<SessionManagerClient> session_manager_client_;
scoped_ptr<SpeechSynthesizerClient> speech_synthesizer_client_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 8c13500..e1fa6d4 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -416,6 +416,10 @@
'browser/chromeos/cros_stubs_aura.cc',
'browser/chromeos/customization_document.cc',
'browser/chromeos/customization_document.h',
+ 'browser/chromeos/dbus/bluetooth_adapter_client.cc',
+ 'browser/chromeos/dbus/bluetooth_adapter_client.h',
+ 'browser/chromeos/dbus/bluetooth_manager_client.cc',
+ 'browser/chromeos/dbus/bluetooth_manager_client.h',
'browser/chromeos/dbus/cros_dbus_service.cc',
'browser/chromeos/dbus/cros_dbus_service.h',
'browser/chromeos/dbus/dbus_thread_manager.cc',