• 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() : weak_ptr_factory_(this) {}
54 
~BluetoothAdapterClientImpl()55   virtual ~BluetoothAdapterClientImpl() {
56     object_manager_->UnregisterInterface(
57         bluetooth_adapter::kBluetoothAdapterInterface);
58   }
59 
60   // BluetoothAdapterClient override.
AddObserver(BluetoothAdapterClient::Observer * observer)61   virtual void AddObserver(BluetoothAdapterClient::Observer* observer)
62       OVERRIDE {
63     DCHECK(observer);
64     observers_.AddObserver(observer);
65   }
66 
67   // BluetoothAdapterClient override.
RemoveObserver(BluetoothAdapterClient::Observer * observer)68   virtual void RemoveObserver(BluetoothAdapterClient::Observer* observer)
69       OVERRIDE {
70     DCHECK(observer);
71     observers_.RemoveObserver(observer);
72   }
73 
74   // Returns the list of adapter object paths known to the system.
GetAdapters()75   virtual std::vector<dbus::ObjectPath> GetAdapters() OVERRIDE {
76     return object_manager_->GetObjectsWithInterface(
77         bluetooth_adapter::kBluetoothAdapterInterface);
78   }
79 
80   // dbus::ObjectManager::Interface override.
CreateProperties(dbus::ObjectProxy * object_proxy,const dbus::ObjectPath & object_path,const std::string & interface_name)81   virtual dbus::PropertySet* CreateProperties(
82       dbus::ObjectProxy* object_proxy,
83       const dbus::ObjectPath& object_path,
84       const std::string& interface_name) OVERRIDE {
85     Properties* properties = new Properties(
86         object_proxy,
87         interface_name,
88         base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged,
89                    weak_ptr_factory_.GetWeakPtr(),
90                    object_path));
91     return static_cast<dbus::PropertySet*>(properties);
92   }
93 
94   // BluetoothAdapterClient override.
GetProperties(const dbus::ObjectPath & object_path)95   virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
96       OVERRIDE {
97     return static_cast<Properties*>(
98         object_manager_->GetProperties(
99             object_path,
100             bluetooth_adapter::kBluetoothAdapterInterface));
101   }
102 
103   // BluetoothAdapterClient override.
StartDiscovery(const dbus::ObjectPath & object_path,const base::Closure & callback,const ErrorCallback & error_callback)104   virtual void StartDiscovery(const dbus::ObjectPath& object_path,
105                               const base::Closure& callback,
106                               const ErrorCallback& error_callback) OVERRIDE {
107     dbus::MethodCall method_call(
108         bluetooth_adapter::kBluetoothAdapterInterface,
109         bluetooth_adapter::kStartDiscovery);
110 
111     dbus::ObjectProxy* object_proxy =
112         object_manager_->GetObjectProxy(object_path);
113     if (!object_proxy) {
114       error_callback.Run(kUnknownAdapterError, "");
115       return;
116     }
117 
118     object_proxy->CallMethodWithErrorCallback(
119         &method_call,
120         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
121         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
122                    weak_ptr_factory_.GetWeakPtr(), callback),
123         base::Bind(&BluetoothAdapterClientImpl::OnError,
124                    weak_ptr_factory_.GetWeakPtr(), error_callback));
125   }
126 
127   // BluetoothAdapterClient override.
StopDiscovery(const dbus::ObjectPath & object_path,const base::Closure & callback,const ErrorCallback & error_callback)128   virtual void StopDiscovery(const dbus::ObjectPath& object_path,
129                              const base::Closure& callback,
130                              const ErrorCallback& error_callback) OVERRIDE {
131     dbus::MethodCall method_call(
132         bluetooth_adapter::kBluetoothAdapterInterface,
133         bluetooth_adapter::kStopDiscovery);
134 
135     dbus::ObjectProxy* object_proxy =
136         object_manager_->GetObjectProxy(object_path);
137     if (!object_proxy) {
138       error_callback.Run(kUnknownAdapterError, "");
139       return;
140     }
141 
142     object_proxy->CallMethodWithErrorCallback(
143         &method_call,
144         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
145         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
146                    weak_ptr_factory_.GetWeakPtr(), callback),
147         base::Bind(&BluetoothAdapterClientImpl::OnError,
148                    weak_ptr_factory_.GetWeakPtr(), error_callback));
149   }
150 
151   // BluetoothAdapterClient override.
RemoveDevice(const dbus::ObjectPath & object_path,const dbus::ObjectPath & device_path,const base::Closure & callback,const ErrorCallback & error_callback)152   virtual void RemoveDevice(const dbus::ObjectPath& object_path,
153                             const dbus::ObjectPath& device_path,
154                             const base::Closure& callback,
155                             const ErrorCallback& error_callback) OVERRIDE {
156     dbus::MethodCall method_call(
157         bluetooth_adapter::kBluetoothAdapterInterface,
158         bluetooth_adapter::kRemoveDevice);
159 
160     dbus::MessageWriter writer(&method_call);
161     writer.AppendObjectPath(device_path);
162 
163     dbus::ObjectProxy* object_proxy =
164         object_manager_->GetObjectProxy(object_path);
165     if (!object_proxy) {
166       error_callback.Run(kUnknownAdapterError, "");
167       return;
168     }
169 
170     object_proxy->CallMethodWithErrorCallback(
171         &method_call,
172         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
173         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
174                    weak_ptr_factory_.GetWeakPtr(), callback),
175         base::Bind(&BluetoothAdapterClientImpl::OnError,
176                    weak_ptr_factory_.GetWeakPtr(), error_callback));
177   }
178 
179  protected:
Init(dbus::Bus * bus)180   virtual void Init(dbus::Bus* bus) OVERRIDE {
181     object_manager_ = bus->GetObjectManager(
182         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
183         dbus::ObjectPath(
184             bluetooth_object_manager::kBluetoothObjectManagerServicePath));
185     object_manager_->RegisterInterface(
186         bluetooth_adapter::kBluetoothAdapterInterface, this);
187   }
188 
189  private:
190   // Called by dbus::ObjectManager when an object with the adapter interface
191   // is created. Informs observers.
ObjectAdded(const dbus::ObjectPath & object_path,const std::string & interface_name)192   virtual void ObjectAdded(const dbus::ObjectPath& object_path,
193                            const std::string& interface_name) OVERRIDE {
194     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
195                       AdapterAdded(object_path));
196   }
197 
198   // Called by dbus::ObjectManager when an object with the adapter interface
199   // is removed. Informs observers.
ObjectRemoved(const dbus::ObjectPath & object_path,const std::string & interface_name)200   virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
201                              const std::string& interface_name) OVERRIDE {
202     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
203                       AdapterRemoved(object_path));
204   }
205 
206   // Called by dbus::PropertySet when a property value is changed,
207   // either by result of a signal or response to a GetAll() or Get()
208   // call. Informs observers.
OnPropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)209   void OnPropertyChanged(const dbus::ObjectPath& object_path,
210                          const std::string& property_name) {
211     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
212                       AdapterPropertyChanged(object_path, property_name));
213   }
214 
215   // Called when a response for successful method call is received.
OnSuccess(const base::Closure & callback,dbus::Response * response)216   void OnSuccess(const base::Closure& callback,
217                  dbus::Response* response) {
218     DCHECK(response);
219     callback.Run();
220   }
221 
222   // Called when a response for a failed method call is received.
OnError(const ErrorCallback & error_callback,dbus::ErrorResponse * response)223   void OnError(const ErrorCallback& error_callback,
224                dbus::ErrorResponse* response) {
225     // Error response has optional error message argument.
226     std::string error_name;
227     std::string error_message;
228     if (response) {
229       dbus::MessageReader reader(response);
230       error_name = response->GetErrorName();
231       reader.PopString(&error_message);
232     } else {
233       error_name = kNoResponseError;
234       error_message = "";
235     }
236     error_callback.Run(error_name, error_message);
237   }
238 
239   dbus::ObjectManager* object_manager_;
240 
241   // List of observers interested in event notifications from us.
242   ObserverList<BluetoothAdapterClient::Observer> observers_;
243 
244   // Weak pointer factory for generating 'this' pointers that might live longer
245   // than we do.
246   // Note: This should remain the last member so it'll be destroyed and
247   // invalidate its weak pointers before any other members are destroyed.
248   base::WeakPtrFactory<BluetoothAdapterClientImpl>
249       weak_ptr_factory_;
250 
251   DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl);
252 };
253 
BluetoothAdapterClient()254 BluetoothAdapterClient::BluetoothAdapterClient() {
255 }
256 
~BluetoothAdapterClient()257 BluetoothAdapterClient::~BluetoothAdapterClient() {
258 }
259 
Create()260 BluetoothAdapterClient* BluetoothAdapterClient::Create() {
261   return new BluetoothAdapterClientImpl;
262 }
263 
264 }  // namespace chromeos
265