[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_input_client.cc
blob62d370d664e4f1617ec871eef86616b2a70a8d34
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_input_client.h"
7 #include <map>
8 #include <utility>
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "base/stl_util.h"
13 #include "chromeos/dbus/bluetooth_adapter_client.h"
14 #include "chromeos/dbus/bluetooth_property.h"
15 #include "dbus/bus.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"
21 namespace chromeos {
23 const char BluetoothInputClient::kNoResponseError[] =
24 "org.chromium.Error.NoResponse";
26 BluetoothInputClient::Properties::Properties(
27 dbus::ObjectProxy* object_proxy,
28 const PropertyChangedCallback& callback)
29 : BluetoothPropertySet(object_proxy,
30 bluetooth_input::kBluetoothInputInterface,
31 callback) {
32 RegisterProperty(bluetooth_input::kConnectedProperty, &connected);
35 BluetoothInputClient::Properties::~Properties() {
39 // The BluetoothInputClient implementation used in production.
40 class BluetoothInputClientImpl: public BluetoothInputClient,
41 private BluetoothAdapterClient::Observer {
42 public:
43 BluetoothInputClientImpl(dbus::Bus* bus,
44 BluetoothAdapterClient* adapter_client)
45 : bus_(bus),
46 weak_ptr_factory_(this) {
47 DVLOG(1) << "Creating BluetoothInputClientImpl";
49 DCHECK(adapter_client);
50 adapter_client->AddObserver(this);
53 virtual ~BluetoothInputClientImpl() {
54 // Clean up Properties structures
55 for (ObjectMap::iterator iter = object_map_.begin();
56 iter != object_map_.end(); ++iter) {
57 Object object = iter->second;
58 Properties* properties = object.second;
59 delete properties;
63 // BluetoothInputClient override.
64 virtual void AddObserver(BluetoothInputClient::Observer* observer)
65 OVERRIDE {
66 DCHECK(observer);
67 observers_.AddObserver(observer);
70 // BluetoothInputClient override.
71 virtual void RemoveObserver(BluetoothInputClient::Observer* observer)
72 OVERRIDE {
73 DCHECK(observer);
74 observers_.RemoveObserver(observer);
77 // BluetoothInputClient override.
78 virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
79 OVERRIDE {
80 return GetObject(object_path).second;
83 // BluetoothInputClient override.
84 virtual void Connect(const dbus::ObjectPath& object_path,
85 const ConnectCallback& callback,
86 const ConnectErrorCallback& error_callback) OVERRIDE {
87 dbus::MethodCall method_call(
88 bluetooth_input::kBluetoothInputInterface,
89 bluetooth_input::kConnect);
91 dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path);
93 object_proxy->CallMethodWithErrorCallback(
94 &method_call,
95 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
96 base::Bind(&BluetoothInputClientImpl::OnConnect,
97 weak_ptr_factory_.GetWeakPtr(), object_path,
98 callback),
99 base::Bind(&BluetoothInputClientImpl::OnConnectError,
100 weak_ptr_factory_.GetWeakPtr(), object_path,
101 error_callback));
104 // BluetoothInputClient override.
105 virtual void Disconnect(const dbus::ObjectPath& object_path,
106 const InputCallback& callback) OVERRIDE {
107 dbus::MethodCall method_call(
108 bluetooth_input::kBluetoothInputInterface,
109 bluetooth_input::kDisconnect);
111 dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path);
113 object_proxy->CallMethod(
114 &method_call,
115 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
116 base::Bind(&BluetoothInputClientImpl::OnDisconnect,
117 weak_ptr_factory_.GetWeakPtr(), object_path, callback));
120 private:
121 // We maintain a collection of dbus object proxies and properties structures
122 // for each input device.
123 typedef std::pair<dbus::ObjectProxy*, Properties*> Object;
124 typedef std::map<const dbus::ObjectPath, Object> ObjectMap;
125 ObjectMap object_map_;
127 // BluetoothAdapterClient::Observer override.
128 virtual void DeviceCreated(const dbus::ObjectPath& adapter_path,
129 const dbus::ObjectPath& object_path) OVERRIDE {
132 // BluetoothAdapterClient::Observer override.
133 virtual void DeviceRemoved(const dbus::ObjectPath& adapter_path,
134 const dbus::ObjectPath& object_path) OVERRIDE {
135 RemoveObject(object_path);
138 // Ensures that we have an object proxy and properties structure for
139 // an input device with object path |object_path|, creating it if not and
140 // storing it in our |object_map_| map.
141 Object GetObject(const dbus::ObjectPath& object_path) {
142 ObjectMap::iterator iter = object_map_.find(object_path);
143 if (iter != object_map_.end())
144 return iter->second;
146 // Create the object proxy.
147 DCHECK(bus_);
148 dbus::ObjectProxy* object_proxy = bus_->GetObjectProxy(
149 bluetooth_input::kBluetoothInputServiceName, object_path);
151 // Create the properties structure.
152 Properties* properties = new Properties(
153 object_proxy,
154 base::Bind(&BluetoothInputClientImpl::OnPropertyChanged,
155 weak_ptr_factory_.GetWeakPtr(), object_path));
157 properties->ConnectSignals();
158 properties->GetAll();
160 Object object = std::make_pair(object_proxy, properties);
161 object_map_[object_path] = object;
162 return object;
165 // Removes the dbus object proxy and properties for the input device with
166 // dbus object path |object_path| from our |object_map_| map.
167 void RemoveObject(const dbus::ObjectPath& object_path) {
168 ObjectMap::iterator iter = object_map_.find(object_path);
169 if (iter != object_map_.end()) {
170 // Clean up the Properties structure.
171 Object object = iter->second;
172 Properties* properties = object.second;
173 delete properties;
175 object_map_.erase(iter);
179 // Returns a pointer to the object proxy for |object_path|, creating
180 // it if necessary.
181 dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path) {
182 return GetObject(object_path).first;
185 // Called by BluetoothPropertySet when a property value is changed,
186 // either by result of a signal or response to a GetAll() or Get()
187 // call. Informs observers.
188 void OnPropertyChanged(const dbus::ObjectPath& object_path,
189 const std::string& property_name) {
190 FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_,
191 InputPropertyChanged(object_path, property_name));
194 // Called when a response for Connect() is received.
195 void OnConnect(const dbus::ObjectPath& object_path,
196 const ConnectCallback& callback,
197 dbus::Response* response) {
198 DCHECK(response);
199 callback.Run(object_path);
202 // Called when an error for Connect() is received.
203 void OnConnectError(const dbus::ObjectPath& object_path,
204 const ConnectErrorCallback& error_callback,
205 dbus::ErrorResponse* response) {
206 // Error response has optional error message argument.
207 std::string error_name;
208 std::string error_message;
209 if (response) {
210 dbus::MessageReader reader(response);
211 error_name = response->GetErrorName();
212 error_message = reader.PopString(&error_message);
213 } else {
214 error_name = kNoResponseError;
215 error_message = "";
217 error_callback.Run(object_path, error_name, error_message);
220 // Called when a response for Disconnect() is received.
221 void OnDisconnect(const dbus::ObjectPath& object_path,
222 const InputCallback& callback,
223 dbus::Response* response) {
224 LOG_IF(WARNING, !response) << object_path.value()
225 << ": OnDisconnect: failed.";
226 callback.Run(object_path, response);
229 dbus::Bus* bus_;
231 // List of observers interested in event notifications from us.
232 ObserverList<BluetoothInputClient::Observer> observers_;
234 // Weak pointer factory for generating 'this' pointers that might live longer
235 // than we do.
236 // Note: This should remain the last member so it'll be destroyed and
237 // invalidate its weak pointers before any other members are destroyed.
238 base::WeakPtrFactory<BluetoothInputClientImpl> weak_ptr_factory_;
240 DISALLOW_COPY_AND_ASSIGN(BluetoothInputClientImpl);
243 // The BluetoothInputClient implementation used on Linux desktop, which does
244 // nothing.
245 class BluetoothInputClientStubImpl : public BluetoothInputClient {
246 public:
247 // BluetoothInputClient override.
248 virtual void AddObserver(Observer* observer) OVERRIDE {
251 // BluetoothInputClient override.
252 virtual void RemoveObserver(Observer* observer) OVERRIDE {
255 // BluetoothInputClient override.
256 virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
257 OVERRIDE {
258 VLOG(1) << "GetProperties: " << object_path.value();
259 return NULL;
262 // BluetoothInputClient override.
263 virtual void Connect(const dbus::ObjectPath& object_path,
264 const ConnectCallback& callback,
265 const ConnectErrorCallback& error_callback) OVERRIDE {
266 VLOG(1) << "Connect: " << object_path.value();
267 error_callback.Run(object_path, "", "");
270 // BluetoothInputClient override.
271 virtual void Disconnect(const dbus::ObjectPath& object_path,
272 const InputCallback& callback) OVERRIDE {
273 VLOG(1) << "Disconnect: " << object_path.value();
274 callback.Run(object_path, false);
278 BluetoothInputClient::BluetoothInputClient() {
281 BluetoothInputClient::~BluetoothInputClient() {
284 BluetoothInputClient* BluetoothInputClient::Create(
285 DBusClientImplementationType type,
286 dbus::Bus* bus,
287 BluetoothAdapterClient* adapter_client) {
288 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
289 return new BluetoothInputClientImpl(bus, adapter_client);
290 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
291 return new BluetoothInputClientStubImpl();
294 } // namespace chromeos