• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chromeos/dbus/bluetooth_adapter_client.h"
6 
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "dbus/bus.h"
10 #include "dbus/message.h"
11 #include "dbus/object_manager.h"
12 #include "dbus/object_path.h"
13 #include "dbus/object_proxy.h"
14 #include "third_party/cros_system_api/dbus/service_constants.h"
15 
16 namespace chromeos {
17 
18 const char BluetoothAdapterClient::kNoResponseError[] =
19     "org.chromium.Error.NoResponse";
20 const char BluetoothAdapterClient::kUnknownAdapterError[] =
21     "org.chromium.Error.UnknownAdapter";
22 
Properties(dbus::ObjectProxy * object_proxy,const std::string & interface_name,const PropertyChangedCallback & callback)23 BluetoothAdapterClient::Properties::Properties(
24     dbus::ObjectProxy* object_proxy,
25     const std::string& interface_name,
26     const PropertyChangedCallback& callback)
27     : dbus::PropertySet(object_proxy, interface_name, callback) {
28   RegisterProperty(bluetooth_adapter::kAddressProperty, &address);
29   RegisterProperty(bluetooth_adapter::kNameProperty, &name);
30   RegisterProperty(bluetooth_adapter::kAliasProperty, &alias);
31   RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class);
32   RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered);
33   RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable);
34   RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable);
35   RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty,
36                    &pairable_timeout);
37   RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty,
38                    &discoverable_timeout);
39   RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering);
40   RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids);
41   RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias);
42 }
43 
~Properties()44 BluetoothAdapterClient::Properties::~Properties() {
45 }
46 
47 
48 // The BluetoothAdapterClient implementation used in production.
49 class BluetoothAdapterClientImpl
50     : public BluetoothAdapterClient,
51       public dbus::ObjectManager::Interface {
52  public:
BluetoothAdapterClientImpl()53   BluetoothAdapterClientImpl()
54       : object_manager_(NULL), weak_ptr_factory_(this) {}
55 
~BluetoothAdapterClientImpl()56   virtual ~BluetoothAdapterClientImpl() {
57     object_manager_->UnregisterInterface(
58         bluetooth_adapter::kBluetoothAdapterInterface);
59   }
60 
61   // BluetoothAdapterClient override.
AddObserver(BluetoothAdapterClient::Observer * observer)62   virtual void AddObserver(BluetoothAdapterClient::Observer* observer)
63       OVERRIDE {
64     DCHECK(observer);
65     observers_.AddObserver(observer);
66   }
67 
68   // BluetoothAdapterClient override.
RemoveObserver(BluetoothAdapterClient::Observer * observer)69   virtual void RemoveObserver(BluetoothAdapterClient::Observer* observer)
70       OVERRIDE {
71     DCHECK(observer);
72     observers_.RemoveObserver(observer);
73   }
74 
75   // Returns the list of adapter object paths known to the system.
GetAdapters()76   virtual std::vector<dbus::ObjectPath> GetAdapters() OVERRIDE {
77     return object_manager_->GetObjectsWithInterface(
78         bluetooth_adapter::kBluetoothAdapterInterface);
79   }
80 
81   // dbus::ObjectManager::Interface override.
CreateProperties(dbus::ObjectProxy * object_proxy,const dbus::ObjectPath & object_path,const std::string & interface_name)82   virtual dbus::PropertySet* CreateProperties(
83       dbus::ObjectProxy* object_proxy,
84       const dbus::ObjectPath& object_path,
85       const std::string& interface_name) OVERRIDE {
86     Properties* properties = new Properties(
87         object_proxy,
88         interface_name,
89         base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged,
90                    weak_ptr_factory_.GetWeakPtr(),
91                    object_path));
92     return static_cast<dbus::PropertySet*>(properties);
93   }
94 
95   // BluetoothAdapterClient override.
GetProperties(const dbus::ObjectPath & object_path)96   virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
97       OVERRIDE {
98     return static_cast<Properties*>(
99         object_manager_->GetProperties(
100             object_path,
101             bluetooth_adapter::kBluetoothAdapterInterface));
102   }
103 
104   // BluetoothAdapterClient override.
StartDiscovery(const dbus::ObjectPath & object_path,const base::Closure & callback,const ErrorCallback & error_callback)105   virtual void StartDiscovery(const dbus::ObjectPath& object_path,
106                               const base::Closure& callback,
107                               const ErrorCallback& error_callback) OVERRIDE {
108     dbus::MethodCall method_call(
109         bluetooth_adapter::kBluetoothAdapterInterface,
110         bluetooth_adapter::kStartDiscovery);
111 
112     dbus::ObjectProxy* object_proxy =
113         object_manager_->GetObjectProxy(object_path);
114     if (!object_proxy) {
115       error_callback.Run(kUnknownAdapterError, "");
116       return;
117     }
118 
119     object_proxy->CallMethodWithErrorCallback(
120         &method_call,
121         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
122         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
123                    weak_ptr_factory_.GetWeakPtr(), callback),
124         base::Bind(&BluetoothAdapterClientImpl::OnError,
125                    weak_ptr_factory_.GetWeakPtr(), error_callback));
126   }
127 
128   // BluetoothAdapterClient override.
StopDiscovery(const dbus::ObjectPath & object_path,const base::Closure & callback,const ErrorCallback & error_callback)129   virtual void StopDiscovery(const dbus::ObjectPath& object_path,
130                              const base::Closure& callback,
131                              const ErrorCallback& error_callback) OVERRIDE {
132     dbus::MethodCall method_call(
133         bluetooth_adapter::kBluetoothAdapterInterface,
134         bluetooth_adapter::kStopDiscovery);
135 
136     dbus::ObjectProxy* object_proxy =
137         object_manager_->GetObjectProxy(object_path);
138     if (!object_proxy) {
139       error_callback.Run(kUnknownAdapterError, "");
140       return;
141     }
142 
143     object_proxy->CallMethodWithErrorCallback(
144         &method_call,
145         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
146         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
147                    weak_ptr_factory_.GetWeakPtr(), callback),
148         base::Bind(&BluetoothAdapterClientImpl::OnError,
149                    weak_ptr_factory_.GetWeakPtr(), error_callback));
150   }
151 
152   // BluetoothAdapterClient override.
RemoveDevice(const dbus::ObjectPath & object_path,const dbus::ObjectPath & device_path,const base::Closure & callback,const ErrorCallback & error_callback)153   virtual void RemoveDevice(const dbus::ObjectPath& object_path,
154                             const dbus::ObjectPath& device_path,
155                             const base::Closure& callback,
156                             const ErrorCallback& error_callback) OVERRIDE {
157     dbus::MethodCall method_call(
158         bluetooth_adapter::kBluetoothAdapterInterface,
159         bluetooth_adapter::kRemoveDevice);
160 
161     dbus::MessageWriter writer(&method_call);
162     writer.AppendObjectPath(device_path);
163 
164     dbus::ObjectProxy* object_proxy =
165         object_manager_->GetObjectProxy(object_path);
166     if (!object_proxy) {
167       error_callback.Run(kUnknownAdapterError, "");
168       return;
169     }
170 
171     object_proxy->CallMethodWithErrorCallback(
172         &method_call,
173         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
174         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
175                    weak_ptr_factory_.GetWeakPtr(), callback),
176         base::Bind(&BluetoothAdapterClientImpl::OnError,
177                    weak_ptr_factory_.GetWeakPtr(), error_callback));
178   }
179 
180  protected:
Init(dbus::Bus * bus)181   virtual void Init(dbus::Bus* bus) OVERRIDE {
182     object_manager_ = bus->GetObjectManager(
183         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
184         dbus::ObjectPath(
185             bluetooth_object_manager::kBluetoothObjectManagerServicePath));
186     object_manager_->RegisterInterface(
187         bluetooth_adapter::kBluetoothAdapterInterface, this);
188   }
189 
190  private:
191   // Called by dbus::ObjectManager when an object with the adapter interface
192   // is created. Informs observers.
ObjectAdded(const dbus::ObjectPath & object_path,const std::string & interface_name)193   virtual void ObjectAdded(const dbus::ObjectPath& object_path,
194                            const std::string& interface_name) OVERRIDE {
195     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
196                       AdapterAdded(object_path));
197   }
198 
199   // Called by dbus::ObjectManager when an object with the adapter interface
200   // is removed. Informs observers.
ObjectRemoved(const dbus::ObjectPath & object_path,const std::string & interface_name)201   virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
202                              const std::string& interface_name) OVERRIDE {
203     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
204                       AdapterRemoved(object_path));
205   }
206 
207   // Called by dbus::PropertySet when a property value is changed,
208   // either by result of a signal or response to a GetAll() or Get()
209   // call. Informs observers.
OnPropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)210   void OnPropertyChanged(const dbus::ObjectPath& object_path,
211                          const std::string& property_name) {
212     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
213                       AdapterPropertyChanged(object_path, property_name));
214   }
215 
216   // Called when a response for successful method call is received.
OnSuccess(const base::Closure & callback,dbus::Response * response)217   void OnSuccess(const base::Closure& callback,
218                  dbus::Response* response) {
219     DCHECK(response);
220     callback.Run();
221   }
222 
223   // Called when a response for a failed method call is received.
OnError(const ErrorCallback & error_callback,dbus::ErrorResponse * response)224   void OnError(const ErrorCallback& error_callback,
225                dbus::ErrorResponse* response) {
226     // Error response has optional error message argument.
227     std::string error_name;
228     std::string error_message;
229     if (response) {
230       dbus::MessageReader reader(response);
231       error_name = response->GetErrorName();
232       reader.PopString(&error_message);
233     } else {
234       error_name = kNoResponseError;
235       error_message = "";
236     }
237     error_callback.Run(error_name, error_message);
238   }
239 
240   dbus::ObjectManager* object_manager_;
241 
242   // List of observers interested in event notifications from us.
243   ObserverList<BluetoothAdapterClient::Observer> observers_;
244 
245   // Weak pointer factory for generating 'this' pointers that might live longer
246   // than we do.
247   // Note: This should remain the last member so it'll be destroyed and
248   // invalidate its weak pointers before any other members are destroyed.
249   base::WeakPtrFactory<BluetoothAdapterClientImpl>
250       weak_ptr_factory_;
251 
252   DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl);
253 };
254 
BluetoothAdapterClient()255 BluetoothAdapterClient::BluetoothAdapterClient() {
256 }
257 
~BluetoothAdapterClient()258 BluetoothAdapterClient::~BluetoothAdapterClient() {
259 }
260 
Create()261 BluetoothAdapterClient* BluetoothAdapterClient::Create() {
262   return new BluetoothAdapterClientImpl;
263 }
264 
265 }  // namespace chromeos
266