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"
9 #include "base/logging.h"
11 #include "dbus/message.h"
12 #include "dbus/object_path.h"
13 #include "dbus/object_proxy.h"
18 // PropertyBase implementation.
21 void PropertyBase::Init(PropertySet
* property_set
, const std::string
& name
) {
22 DCHECK(!property_set_
);
23 property_set_
= property_set
;
29 // PropertySet implementation.
32 PropertySet::PropertySet(
33 ObjectProxy
* object_proxy
,
34 const std::string
& interface
,
35 const PropertyChangedCallback
& property_changed_callback
)
36 : object_proxy_(object_proxy
),
37 interface_(interface
),
38 property_changed_callback_(property_changed_callback
),
39 weak_ptr_factory_(this) {}
41 PropertySet::~PropertySet() {
44 void PropertySet::RegisterProperty(const std::string
& name
,
45 PropertyBase
* property
) {
46 property
->Init(this, name
);
47 properties_map_
[name
] = property
;
50 void PropertySet::ConnectSignals() {
51 DCHECK(object_proxy_
);
52 object_proxy_
->ConnectToSignal(
55 base::Bind(&PropertySet::ChangedReceived
,
56 weak_ptr_factory_
.GetWeakPtr()),
57 base::Bind(&PropertySet::ChangedConnected
,
58 weak_ptr_factory_
.GetWeakPtr()));
62 void PropertySet::ChangedReceived(Signal
* signal
) {
64 MessageReader
reader(signal
);
66 std::string interface
;
67 if (!reader
.PopString(&interface
)) {
68 LOG(WARNING
) << "Property changed signal has wrong parameters: "
69 << "expected interface name: " << signal
->ToString();
73 if (interface
!= this->interface())
76 if (!UpdatePropertiesFromReader(&reader
)) {
77 LOG(WARNING
) << "Property changed signal has wrong parameters: "
78 << "expected dictionary: " << signal
->ToString();
81 if (!InvalidatePropertiesFromReader(&reader
)) {
82 LOG(WARNING
) << "Property changed signal has wrong parameters: "
83 << "expected array to invalidate: " << signal
->ToString();
87 void PropertySet::ChangedConnected(const std::string
& interface_name
,
88 const std::string
& signal_name
,
90 LOG_IF(WARNING
, !success
) << "Failed to connect to " << signal_name
95 void PropertySet::Get(PropertyBase
* property
, GetCallback callback
) {
96 MethodCall
method_call(kPropertiesInterface
, kPropertiesGet
);
97 MessageWriter
writer(&method_call
);
98 writer
.AppendString(interface());
99 writer
.AppendString(property
->name());
101 DCHECK(object_proxy_
);
102 object_proxy_
->CallMethod(&method_call
,
103 ObjectProxy::TIMEOUT_USE_DEFAULT
,
104 base::Bind(&PropertySet::OnGet
,
110 void PropertySet::OnGet(PropertyBase
* property
, GetCallback callback
,
111 Response
* response
) {
113 LOG(WARNING
) << property
->name() << ": Get: failed.";
117 MessageReader
reader(response
);
118 if (property
->PopValueFromReader(&reader
)) {
119 property
->set_valid(true);
120 NotifyPropertyChanged(property
->name());
122 if (property
->is_valid()) {
123 property
->set_valid(false);
124 NotifyPropertyChanged(property
->name());
128 if (!callback
.is_null())
129 callback
.Run(response
);
132 void PropertySet::GetAll() {
133 MethodCall
method_call(kPropertiesInterface
, kPropertiesGetAll
);
134 MessageWriter
writer(&method_call
);
135 writer
.AppendString(interface());
137 DCHECK(object_proxy_
);
138 object_proxy_
->CallMethod(&method_call
,
139 ObjectProxy::TIMEOUT_USE_DEFAULT
,
140 base::Bind(&PropertySet::OnGetAll
,
141 weak_ptr_factory_
.GetWeakPtr()));
144 void PropertySet::OnGetAll(Response
* response
) {
146 LOG(WARNING
) << "GetAll request failed for: " << interface_
;
150 MessageReader
reader(response
);
151 if (!UpdatePropertiesFromReader(&reader
)) {
152 LOG(WARNING
) << "GetAll response has wrong parameters: "
153 << "expected dictionary: " << response
->ToString();
157 void PropertySet::Set(PropertyBase
* property
, SetCallback callback
) {
158 MethodCall
method_call(kPropertiesInterface
, kPropertiesSet
);
159 MessageWriter
writer(&method_call
);
160 writer
.AppendString(interface());
161 writer
.AppendString(property
->name());
162 property
->AppendSetValueToWriter(&writer
);
164 DCHECK(object_proxy_
);
165 object_proxy_
->CallMethod(&method_call
,
166 ObjectProxy::TIMEOUT_USE_DEFAULT
,
167 base::Bind(&PropertySet::OnSet
,
173 void PropertySet::OnSet(PropertyBase
* property
,
174 SetCallback callback
,
175 Response
* response
) {
176 LOG_IF(WARNING
, !response
) << property
->name() << ": Set: failed.";
177 if (!callback
.is_null())
178 callback
.Run(response
);
181 bool PropertySet::UpdatePropertiesFromReader(MessageReader
* reader
) {
183 MessageReader
array_reader(NULL
);
184 if (!reader
->PopArray(&array_reader
))
187 while (array_reader
.HasMoreData()) {
188 MessageReader
dict_entry_reader(NULL
);
189 if (array_reader
.PopDictEntry(&dict_entry_reader
))
190 UpdatePropertyFromReader(&dict_entry_reader
);
196 bool PropertySet::UpdatePropertyFromReader(MessageReader
* reader
) {
200 if (!reader
->PopString(&name
))
203 PropertiesMap::iterator it
= properties_map_
.find(name
);
204 if (it
== properties_map_
.end())
207 PropertyBase
* property
= it
->second
;
208 if (property
->PopValueFromReader(reader
)) {
209 property
->set_valid(true);
210 NotifyPropertyChanged(name
);
213 if (property
->is_valid()) {
214 property
->set_valid(false);
215 NotifyPropertyChanged(property
->name());
221 bool PropertySet::InvalidatePropertiesFromReader(MessageReader
* reader
) {
223 MessageReader
array_reader(NULL
);
224 if (!reader
->PopArray(&array_reader
))
227 while (array_reader
.HasMoreData()) {
229 if (!array_reader
.PopString(&name
))
232 PropertiesMap::iterator it
= properties_map_
.find(name
);
233 if (it
== properties_map_
.end())
236 PropertyBase
* property
= it
->second
;
237 if (property
->is_valid()) {
238 property
->set_valid(false);
239 NotifyPropertyChanged(property
->name());
246 void PropertySet::NotifyPropertyChanged(const std::string
& name
) {
247 if (!property_changed_callback_
.is_null())
248 property_changed_callback_
.Run(name
);
252 // Property<Byte> specialization.
256 Property
<uint8
>::Property() : value_(0) {
260 bool Property
<uint8
>::PopValueFromReader(MessageReader
* reader
) {
261 return reader
->PopVariantOfByte(&value_
);
265 void Property
<uint8
>::AppendSetValueToWriter(MessageWriter
* writer
) {
266 writer
->AppendVariantOfByte(set_value_
);
270 // Property<bool> specialization.
274 Property
<bool>::Property() : value_(false) {
278 bool Property
<bool>::PopValueFromReader(MessageReader
* reader
) {
279 return reader
->PopVariantOfBool(&value_
);
283 void Property
<bool>::AppendSetValueToWriter(MessageWriter
* writer
) {
284 writer
->AppendVariantOfBool(set_value_
);
288 // Property<int16> specialization.
292 Property
<int16
>::Property() : value_(0) {
296 bool Property
<int16
>::PopValueFromReader(MessageReader
* reader
) {
297 return reader
->PopVariantOfInt16(&value_
);
301 void Property
<int16
>::AppendSetValueToWriter(MessageWriter
* writer
) {
302 writer
->AppendVariantOfInt16(set_value_
);
306 // Property<uint16> specialization.
310 Property
<uint16
>::Property() : value_(0) {
314 bool Property
<uint16
>::PopValueFromReader(MessageReader
* reader
) {
315 return reader
->PopVariantOfUint16(&value_
);
319 void Property
<uint16
>::AppendSetValueToWriter(MessageWriter
* writer
) {
320 writer
->AppendVariantOfUint16(set_value_
);
324 // Property<int32> specialization.
328 Property
<int32
>::Property() : value_(0) {
332 bool Property
<int32
>::PopValueFromReader(MessageReader
* reader
) {
333 return reader
->PopVariantOfInt32(&value_
);
337 void Property
<int32
>::AppendSetValueToWriter(MessageWriter
* writer
) {
338 writer
->AppendVariantOfInt32(set_value_
);
342 // Property<uint32> specialization.
346 Property
<uint32
>::Property() : value_(0) {
350 bool Property
<uint32
>::PopValueFromReader(MessageReader
* reader
) {
351 return reader
->PopVariantOfUint32(&value_
);
355 void Property
<uint32
>::AppendSetValueToWriter(MessageWriter
* writer
) {
356 writer
->AppendVariantOfUint32(set_value_
);
360 // Property<int64> specialization.
364 Property
<int64
>::Property() : value_(0), set_value_(0) {
368 bool Property
<int64
>::PopValueFromReader(MessageReader
* reader
) {
369 return reader
->PopVariantOfInt64(&value_
);
373 void Property
<int64
>::AppendSetValueToWriter(MessageWriter
* writer
) {
374 writer
->AppendVariantOfInt64(set_value_
);
378 // Property<uint64> specialization.
382 Property
<uint64
>::Property() : value_(0) {
386 bool Property
<uint64
>::PopValueFromReader(MessageReader
* reader
) {
387 return reader
->PopVariantOfUint64(&value_
);
391 void Property
<uint64
>::AppendSetValueToWriter(MessageWriter
* writer
) {
392 writer
->AppendVariantOfUint64(set_value_
);
396 // Property<double> specialization.
400 Property
<double>::Property() : value_(0.0) {
404 bool Property
<double>::PopValueFromReader(MessageReader
* reader
) {
405 return reader
->PopVariantOfDouble(&value_
);
409 void Property
<double>::AppendSetValueToWriter(MessageWriter
* writer
) {
410 writer
->AppendVariantOfDouble(set_value_
);
414 // Property<std::string> specialization.
418 bool Property
<std::string
>::PopValueFromReader(MessageReader
* reader
) {
419 return reader
->PopVariantOfString(&value_
);
423 void Property
<std::string
>::AppendSetValueToWriter(MessageWriter
* writer
) {
424 writer
->AppendVariantOfString(set_value_
);
428 // Property<ObjectPath> specialization.
432 bool Property
<ObjectPath
>::PopValueFromReader(MessageReader
* reader
) {
433 return reader
->PopVariantOfObjectPath(&value_
);
437 void Property
<ObjectPath
>::AppendSetValueToWriter(MessageWriter
* writer
) {
438 writer
->AppendVariantOfObjectPath(set_value_
);
442 // Property<std::vector<std::string> > specialization.
446 bool Property
<std::vector
<std::string
> >::PopValueFromReader(
447 MessageReader
* reader
) {
448 MessageReader
variant_reader(NULL
);
449 if (!reader
->PopVariant(&variant_reader
))
453 return variant_reader
.PopArrayOfStrings(&value_
);
457 void Property
<std::vector
<std::string
> >::AppendSetValueToWriter(
458 MessageWriter
* writer
) {
459 MessageWriter
variant_writer(NULL
);
460 writer
->OpenVariant("as", &variant_writer
);
461 variant_writer
.AppendArrayOfStrings(set_value_
);
462 writer
->CloseContainer(&variant_writer
);
466 // Property<std::vector<ObjectPath> > specialization.
470 bool Property
<std::vector
<ObjectPath
> >::PopValueFromReader(
471 MessageReader
* reader
) {
472 MessageReader
variant_reader(NULL
);
473 if (!reader
->PopVariant(&variant_reader
))
477 return variant_reader
.PopArrayOfObjectPaths(&value_
);
481 void Property
<std::vector
<ObjectPath
> >::AppendSetValueToWriter(
482 MessageWriter
* writer
) {
483 MessageWriter
variant_writer(NULL
);
484 writer
->OpenVariant("ao", &variant_writer
);
485 variant_writer
.AppendArrayOfObjectPaths(set_value_
);
486 writer
->CloseContainer(&variant_writer
);
490 // Property<std::vector<uint8> > specialization.
494 bool Property
<std::vector
<uint8
> >::PopValueFromReader(MessageReader
* reader
) {
495 MessageReader
variant_reader(NULL
);
496 if (!reader
->PopVariant(&variant_reader
))
500 const uint8
* bytes
= NULL
;
502 if (!variant_reader
.PopArrayOfBytes(&bytes
, &length
))
504 value_
.assign(bytes
, bytes
+ length
);
509 void Property
<std::vector
<uint8
> >::AppendSetValueToWriter(
510 MessageWriter
* writer
) {
511 MessageWriter
variant_writer(NULL
);
512 writer
->OpenVariant("ay", &variant_writer
);
513 variant_writer
.AppendArrayOfBytes(set_value_
.data(), set_value_
.size());
514 writer
->CloseContainer(&variant_writer
);
518 // Property<std::map<std::string, std::string>> specialization.
522 bool Property
<std::map
<std::string
, std::string
>>::PopValueFromReader(
523 MessageReader
* reader
) {
524 MessageReader
variant_reader(NULL
);
525 MessageReader
array_reader(NULL
);
526 if (!reader
->PopVariant(&variant_reader
) ||
527 !variant_reader
.PopArray(&array_reader
))
530 while (array_reader
.HasMoreData()) {
531 dbus::MessageReader
dict_entry_reader(NULL
);
532 if (!array_reader
.PopDictEntry(&dict_entry_reader
))
536 if (!dict_entry_reader
.PopString(&key
) ||
537 !dict_entry_reader
.PopString(&value
))
545 void Property
<std::map
<std::string
, std::string
>>::AppendSetValueToWriter(
546 MessageWriter
* writer
) {
547 MessageWriter
variant_writer(NULL
);
548 MessageWriter
dict_writer(NULL
);
549 writer
->OpenVariant("a{ss}", &variant_writer
);
550 variant_writer
.OpenArray("{ss}", &dict_writer
);
551 for (const auto& pair
: set_value_
) {
552 dbus::MessageWriter
entry_writer(NULL
);
553 dict_writer
.OpenDictEntry(&entry_writer
);
554 entry_writer
.AppendString(pair
.first
);
555 entry_writer
.AppendString(pair
.second
);
556 dict_writer
.CloseContainer(&entry_writer
);
558 variant_writer
.CloseContainer(&dict_writer
);
559 writer
->CloseContainer(&variant_writer
);
563 // Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
568 bool Property
<std::vector
<std::pair
<std::vector
<uint8_t>, uint16_t>>>::
569 PopValueFromReader(MessageReader
* reader
) {
570 MessageReader
variant_reader(NULL
);
571 MessageReader
array_reader(NULL
);
572 if (!reader
->PopVariant(&variant_reader
) ||
573 !variant_reader
.PopArray(&array_reader
))
577 while (array_reader
.HasMoreData()) {
578 dbus::MessageReader
struct_reader(NULL
);
579 if (!array_reader
.PopStruct(&struct_reader
))
582 std::pair
<std::vector
<uint8_t>, uint16_t> entry
;
583 const uint8
* bytes
= NULL
;
585 if (!struct_reader
.PopArrayOfBytes(&bytes
, &length
))
587 entry
.first
.assign(bytes
, bytes
+ length
);
588 if (!struct_reader
.PopUint16(&entry
.second
))
590 value_
.push_back(entry
);
596 void Property
<std::vector
<std::pair
<std::vector
<uint8_t>, uint16_t>>>::
597 AppendSetValueToWriter(MessageWriter
* writer
) {
598 MessageWriter
variant_writer(NULL
);
599 MessageWriter
array_writer(NULL
);
600 writer
->OpenVariant("a(ayq)", &variant_writer
);
601 variant_writer
.OpenArray("(ayq)", &array_writer
);
602 for (const auto& pair
: set_value_
) {
603 dbus::MessageWriter
struct_writer(nullptr);
604 array_writer
.OpenStruct(&struct_writer
);
605 struct_writer
.AppendArrayOfBytes(std::get
<0>(pair
).data(),
606 std::get
<0>(pair
).size());
607 struct_writer
.AppendUint16(std::get
<1>(pair
));
608 array_writer
.CloseContainer(&struct_writer
);
610 variant_writer
.CloseContainer(&array_writer
);
611 writer
->CloseContainer(&variant_writer
);
614 template class Property
<uint8
>;
615 template class Property
<bool>;
616 template class Property
<int16
>;
617 template class Property
<uint16
>;
618 template class Property
<int32
>;
619 template class Property
<uint32
>;
620 template class Property
<int64
>;
621 template class Property
<uint64
>;
622 template class Property
<double>;
623 template class Property
<std::string
>;
624 template class Property
<ObjectPath
>;
625 template class Property
<std::vector
<std::string
> >;
626 template class Property
<std::vector
<ObjectPath
> >;
627 template class Property
<std::vector
<uint8
> >;
628 template class Property
<std::map
<std::string
, std::string
>>;
629 template class Property
<std::vector
<std::pair
<std::vector
<uint8_t>, uint16_t>>>;