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 "chromeos/dbus/bluetooth_node_client.h"
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "base/stl_util.h"
13 #include "chromeos/dbus/bluetooth_device_client.h"
14 #include "chromeos/dbus/bluetooth_property.h"
16 #include "dbus/message.h"
17 #include "dbus/object_path.h"
18 #include "dbus/object_proxy.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
23 BluetoothNodeClient::Properties::Properties(
24 dbus::ObjectProxy
* object_proxy
,
25 const PropertyChangedCallback
& callback
)
26 : BluetoothPropertySet(object_proxy
,
27 bluetooth_node::kBluetoothNodeInterface
,
29 RegisterProperty(bluetooth_node::kNameProperty
, &name
);
30 RegisterProperty(bluetooth_node::kDeviceProperty
, &device
);
33 BluetoothNodeClient::Properties::~Properties() {
37 // The BluetoothNodeClient implementation used in production.
38 class BluetoothNodeClientImpl
: public BluetoothNodeClient
,
39 private BluetoothDeviceClient::Observer
{
41 BluetoothNodeClientImpl(dbus::Bus
* bus
,
42 BluetoothDeviceClient
* device_client
)
44 weak_ptr_factory_(this) {
45 DCHECK(device_client
);
46 device_client
->AddObserver(this);
49 virtual ~BluetoothNodeClientImpl() {
50 // Clean up Properties structures
51 for (ObjectMap::iterator iter
= object_map_
.begin();
52 iter
!= object_map_
.end(); ++iter
) {
53 Object object
= iter
->second
;
54 Properties
* properties
= object
.second
;
59 // BluetoothNodeClient override.
60 virtual void AddObserver(BluetoothNodeClient::Observer
* observer
)
63 observers_
.AddObserver(observer
);
66 // BluetoothNodeClient override.
67 virtual void RemoveObserver(BluetoothNodeClient::Observer
* observer
)
70 observers_
.RemoveObserver(observer
);
73 // BluetoothNodeClient override.
74 virtual Properties
* GetProperties(const dbus::ObjectPath
& object_path
)
76 return GetObject(object_path
).second
;
80 // We maintain a collection of dbus object proxies and properties structures
81 // for each node binding.
82 typedef std::pair
<dbus::ObjectProxy
*, Properties
*> Object
;
83 typedef std::map
<const dbus::ObjectPath
, Object
> ObjectMap
;
84 ObjectMap object_map_
;
86 // BluetoothDeviceClient::Observer override.
87 virtual void NodeCreated(const dbus::ObjectPath
& device_path
,
88 const dbus::ObjectPath
& object_path
) OVERRIDE
{
91 // BluetoothDeviceClient::Observer override.
92 virtual void NodeRemoved(const dbus::ObjectPath
& device_path
,
93 const dbus::ObjectPath
& object_path
) OVERRIDE
{
94 RemoveObject(object_path
);
97 // Ensures that we have an object proxy and properties structure for
98 // a node binding with object path |object_path|, creating it if not and
99 // storing it in our |object_map_| map.
100 Object
GetObject(const dbus::ObjectPath
& object_path
) {
101 ObjectMap::iterator iter
= object_map_
.find(object_path
);
102 if (iter
!= object_map_
.end())
105 // Create the object proxy.
107 dbus::ObjectProxy
* object_proxy
= bus_
->GetObjectProxy(
108 bluetooth_node::kBluetoothNodeServiceName
, object_path
);
110 // Create the properties structure.
111 Properties
* properties
= new Properties(
113 base::Bind(&BluetoothNodeClientImpl::OnPropertyChanged
,
114 weak_ptr_factory_
.GetWeakPtr(), object_path
));
116 properties
->ConnectSignals();
117 properties
->GetAll();
119 Object object
= std::make_pair(object_proxy
, properties
);
120 object_map_
[object_path
] = object
;
124 // Removes the dbus object proxy and properties for the node binding with
125 // dbus object path |object_path| from our |object_map_| map.
126 void RemoveObject(const dbus::ObjectPath
& object_path
) {
127 ObjectMap::iterator iter
= object_map_
.find(object_path
);
128 if (iter
!= object_map_
.end()) {
129 // Clean up the Properties structure.
130 Object object
= iter
->second
;
131 Properties
* properties
= object
.second
;
134 object_map_
.erase(iter
);
138 // Returns a pointer to the object proxy for |object_path|, creating
140 dbus::ObjectProxy
* GetObjectProxy(const dbus::ObjectPath
& object_path
) {
141 return GetObject(object_path
).first
;
144 // Called by BluetoothPropertySet when a property value is changed,
145 // either by result of a signal or response to a GetAll() or Get()
146 // call. Informs observers.
147 void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
148 const std::string
& property_name
) {
149 FOR_EACH_OBSERVER(BluetoothNodeClient::Observer
, observers_
,
150 NodePropertyChanged(object_path
, property_name
));
155 // List of observers interested in event notifications from us.
156 ObserverList
<BluetoothNodeClient::Observer
> observers_
;
158 // Weak pointer factory for generating 'this' pointers that might live longer
160 // Note: This should remain the last member so it'll be destroyed and
161 // invalidate its weak pointers before any other members are destroyed.
162 base::WeakPtrFactory
<BluetoothNodeClientImpl
> weak_ptr_factory_
;
164 DISALLOW_COPY_AND_ASSIGN(BluetoothNodeClientImpl
);
167 // The BluetoothNodeClient implementation used on Linux desktop, which does
169 class BluetoothNodeClientStubImpl
: public BluetoothNodeClient
{
171 // BluetoothNodeClient override.
172 virtual void AddObserver(Observer
* observer
) OVERRIDE
{
175 // BluetoothNodeClient override.
176 virtual void RemoveObserver(Observer
* observer
) OVERRIDE
{
179 // BluetoothNodeClient override.
180 virtual Properties
* GetProperties(const dbus::ObjectPath
& object_path
)
182 VLOG(1) << "GetProperties: " << object_path
.value();
187 BluetoothNodeClient::BluetoothNodeClient() {
190 BluetoothNodeClient::~BluetoothNodeClient() {
193 BluetoothNodeClient
* BluetoothNodeClient::Create(
194 DBusClientImplementationType type
,
196 BluetoothDeviceClient
* adapter_client
) {
197 if (type
== REAL_DBUS_CLIENT_IMPLEMENTATION
)
198 return new BluetoothNodeClientImpl(bus
, adapter_client
);
199 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION
, type
);
200 return new BluetoothNodeClientStubImpl();
203 } // namespace chromeos