chromeos: bluetooth: add BluetoothNodeClient
[chromium-blink-merge.git] / dbus / property.cc
blob0d6e7f013eaf9d17b6e4303ce53817c92bb59937
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 "dbus/property.h"
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/logging.h"
11 #include "dbus/message.h"
12 #include "dbus/object_path.h"
13 #include "dbus/object_proxy.h"
15 namespace dbus {
18 // PropertyBase implementation.
21 void PropertyBase::Init(PropertySet* property_set, const std::string& name) {
22 DCHECK(!property_set_);
23 property_set_ = property_set;
24 name_ = name;
29 // PropertySet implementation.
32 PropertySet::PropertySet(ObjectProxy* object_proxy,
33 const std::string& interface,
34 PropertyChangedCallback property_changed_callback)
35 : object_proxy_(object_proxy),
36 interface_(interface),
37 property_changed_callback_(property_changed_callback),
38 weak_ptr_factory_(this) {}
40 PropertySet::~PropertySet() {
43 void PropertySet::RegisterProperty(const std::string& name,
44 PropertyBase* property) {
45 property->Init(this, name);
46 properties_map_[name] = property;
49 void PropertySet::ConnectSignals() {
50 DCHECK(object_proxy_);
51 object_proxy_->ConnectToSignal(
52 kPropertiesInterface,
53 kPropertiesChanged,
54 base::Bind(&PropertySet::ChangedReceived,
55 weak_ptr_factory_.GetWeakPtr()),
56 base::Bind(&PropertySet::ChangedConnected,
57 weak_ptr_factory_.GetWeakPtr()));
61 void PropertySet::ChangedReceived(Signal* signal) {
62 DCHECK(signal);
63 MessageReader reader(signal);
65 std::string interface;
66 if (!reader.PopString(&interface)) {
67 LOG(WARNING) << "Property changed signal has wrong parameters: "
68 << "expected interface name: " << signal->ToString();
69 return;
72 if (interface != this->interface())
73 return;
75 if (!UpdatePropertiesFromReader(&reader)) {
76 LOG(WARNING) << "Property changed signal has wrong parameters: "
77 << "expected dictionary: " << signal->ToString();
80 // TODO(keybuk): dbus properties api has invalidated properties array
81 // on the end, we don't handle this right now because I don't know of
82 // any service that sends it - or what they expect us to do with it.
83 // Add later when we need it.
86 void PropertySet::ChangedConnected(const std::string& interface_name,
87 const std::string& signal_name,
88 bool success) {
89 LOG_IF(WARNING, !success) << "Failed to connect to " << signal_name
90 << "signal.";
94 void PropertySet::GetAll() {
95 MethodCall method_call(kPropertiesInterface, kPropertiesGetAll);
96 MessageWriter writer(&method_call);
97 writer.AppendString(interface());
99 DCHECK(object_proxy_);
100 object_proxy_->CallMethod(&method_call,
101 ObjectProxy::TIMEOUT_USE_DEFAULT,
102 base::Bind(&PropertySet::OnGetAll,
103 weak_ptr_factory_.GetWeakPtr()));
106 void PropertySet::OnGetAll(Response* response) {
107 if (!response) {
108 LOG(WARNING) << "GetAll request failed.";
109 return;
112 MessageReader reader(response);
113 if (!UpdatePropertiesFromReader(&reader)) {
114 LOG(WARNING) << "GetAll response has wrong parameters: "
115 << "expected dictionary: " << response->ToString();
120 bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
121 DCHECK(reader);
122 MessageReader array_reader(NULL);
123 if (!reader->PopArray(&array_reader))
124 return false;
126 while (array_reader.HasMoreData()) {
127 MessageReader dict_entry_reader(NULL);
128 if (!array_reader.PopDictEntry(&dict_entry_reader))
129 continue;
131 if (!UpdatePropertyFromReader(&dict_entry_reader))
132 continue;
135 return true;
138 bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
139 DCHECK(reader);
141 std::string name;
142 if (!reader->PopString(&name))
143 return false;
145 PropertiesMap::iterator it = properties_map_.find(name);
146 if (it == properties_map_.end())
147 return false;
149 PropertyBase* property = it->second;
150 if (property->PopValueFromReader(reader)) {
151 NotifyPropertyChanged(name);
152 return true;
153 } else {
154 return false;
159 void PropertySet::NotifyPropertyChanged(const std::string& name) {
160 if (!property_changed_callback_.is_null())
161 property_changed_callback_.Run(name);
165 // Property<Byte> specialization.
168 template <>
169 Property<uint8>::Property() : value_(0),
170 weak_ptr_factory_(this) {
173 template <>
174 bool Property<uint8>::PopValueFromReader(MessageReader* reader) {
175 return reader->PopVariantOfByte(&value_);
178 template <>
179 void Property<uint8>::AppendToWriter(MessageWriter* writer,
180 const uint8& value) {
181 writer->AppendVariantOfByte(value);
185 // Property<bool> specialization.
188 template <>
189 Property<bool>::Property() : value_(false),
190 weak_ptr_factory_(this) {
193 template <>
194 bool Property<bool>::PopValueFromReader(MessageReader* reader) {
195 return reader->PopVariantOfBool(&value_);
198 template <>
199 void Property<bool>::AppendToWriter(MessageWriter* writer,
200 const bool& value) {
201 writer->AppendVariantOfBool(value);
205 // Property<int16> specialization.
208 template <>
209 Property<int16>::Property() : value_(0),
210 weak_ptr_factory_(this) {
213 template <>
214 bool Property<int16>::PopValueFromReader(MessageReader* reader) {
215 return reader->PopVariantOfInt16(&value_);
218 template <>
219 void Property<int16>::AppendToWriter(MessageWriter* writer,
220 const int16& value) {
221 writer->AppendVariantOfInt16(value);
225 // Property<uint16> specialization.
228 template <>
229 Property<uint16>::Property() : value_(0),
230 weak_ptr_factory_(this) {
233 template <>
234 bool Property<uint16>::PopValueFromReader(MessageReader* reader) {
235 return reader->PopVariantOfUint16(&value_);
238 template <>
239 void Property<uint16>::AppendToWriter(MessageWriter* writer,
240 const uint16& value) {
241 writer->AppendVariantOfUint16(value);
245 // Property<int32> specialization.
248 template <>
249 Property<int32>::Property() : value_(0),
250 weak_ptr_factory_(this) {
253 template <>
254 bool Property<int32>::PopValueFromReader(MessageReader* reader) {
255 return reader->PopVariantOfInt32(&value_);
258 template <>
259 void Property<int32>::AppendToWriter(MessageWriter* writer,
260 const int32& value) {
261 writer->AppendVariantOfInt32(value);
265 // Property<uint32> specialization.
268 template <>
269 Property<uint32>::Property() : value_(0),
270 weak_ptr_factory_(this) {
273 template <>
274 bool Property<uint32>::PopValueFromReader(MessageReader* reader) {
275 return reader->PopVariantOfUint32(&value_);
278 template <>
279 void Property<uint32>::AppendToWriter(MessageWriter* writer,
280 const uint32& value) {
281 writer->AppendVariantOfUint32(value);
285 // Property<int64> specialization.
288 template <>
289 Property<int64>::Property() : value_(0),
290 weak_ptr_factory_(this) {
293 template <>
294 bool Property<int64>::PopValueFromReader(MessageReader* reader) {
295 return reader->PopVariantOfInt64(&value_);
298 template <>
299 void Property<int64>::AppendToWriter(MessageWriter* writer,
300 const int64& value) {
301 writer->AppendVariantOfInt64(value);
305 // Property<uint64> specialization.
308 template <>
309 Property<uint64>::Property() : value_(0),
310 weak_ptr_factory_(this) {
313 template <>
314 bool Property<uint64>::PopValueFromReader(MessageReader* reader) {
315 return reader->PopVariantOfUint64(&value_);
318 template <>
319 void Property<uint64>::AppendToWriter(MessageWriter* writer,
320 const uint64& value) {
321 writer->AppendVariantOfUint64(value);
325 // Property<double> specialization.
328 template <>
329 Property<double>::Property() : value_(0.0),
330 weak_ptr_factory_(this) {
333 template <>
334 bool Property<double>::PopValueFromReader(MessageReader* reader) {
335 return reader->PopVariantOfDouble(&value_);
338 template <>
339 void Property<double>::AppendToWriter(MessageWriter* writer,
340 const double& value) {
341 writer->AppendVariantOfDouble(value);
345 // Property<std::string> specialization.
348 template <>
349 bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
350 return reader->PopVariantOfString(&value_);
353 template <>
354 void Property<std::string>::AppendToWriter(MessageWriter* writer,
355 const std::string& value) {
356 writer->AppendVariantOfString(value);
360 // Property<ObjectPath> specialization.
363 template <>
364 bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
365 return reader->PopVariantOfObjectPath(&value_);
368 template <>
369 void Property<ObjectPath>::AppendToWriter(MessageWriter* writer,
370 const ObjectPath& value) {
371 writer->AppendVariantOfObjectPath(value);
375 // Property<std::vector<std::string> > specialization.
378 template <>
379 bool Property<std::vector<std::string> >::PopValueFromReader(
380 MessageReader* reader) {
381 MessageReader variant_reader(NULL);
382 if (!reader->PopVariant(&variant_reader))
383 return false;
385 return variant_reader.PopArrayOfStrings(&value_);
388 template <>
389 void Property<std::vector<std::string> >::AppendToWriter(
390 MessageWriter* writer,
391 const std::vector<std::string>& value) {
392 MessageWriter variant_writer(NULL);
393 writer->OpenVariant("as", &variant_writer);
394 variant_writer.AppendArrayOfStrings(value);
395 writer->CloseContainer(&variant_writer);
399 // Property<std::vector<ObjectPath> > specialization.
402 template <>
403 bool Property<std::vector<ObjectPath> >::PopValueFromReader(
404 MessageReader* reader) {
405 MessageReader variant_reader(NULL);
406 if (!reader->PopVariant(&variant_reader))
407 return false;
409 return variant_reader.PopArrayOfObjectPaths(&value_);
412 template <>
413 void Property<std::vector<ObjectPath> >::AppendToWriter(
414 MessageWriter* writer,
415 const std::vector<ObjectPath>& value) {
416 MessageWriter variant_writer(NULL);
417 writer->OpenVariant("ao", &variant_writer);
418 variant_writer.AppendArrayOfObjectPaths(value);
419 writer->CloseContainer(&variant_writer);
422 } // namespace dbus