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 // TODO(keybuk): dbus properties api has invalidated properties array
82 // on the end, we don't handle this right now because I don't know of
83 // any service that sends it - or what they expect us to do with it.
84 // Add later when we need it.
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 NotifyPropertyChanged(property
->name());
121 if (!callback
.is_null())
122 callback
.Run(response
);
125 void PropertySet::GetAll() {
126 MethodCall
method_call(kPropertiesInterface
, kPropertiesGetAll
);
127 MessageWriter
writer(&method_call
);
128 writer
.AppendString(interface());
130 DCHECK(object_proxy_
);
131 object_proxy_
->CallMethod(&method_call
,
132 ObjectProxy::TIMEOUT_USE_DEFAULT
,
133 base::Bind(&PropertySet::OnGetAll
,
134 weak_ptr_factory_
.GetWeakPtr()));
137 void PropertySet::OnGetAll(Response
* response
) {
139 LOG(WARNING
) << "GetAll request failed.";
143 MessageReader
reader(response
);
144 if (!UpdatePropertiesFromReader(&reader
)) {
145 LOG(WARNING
) << "GetAll response has wrong parameters: "
146 << "expected dictionary: " << response
->ToString();
150 void PropertySet::Set(PropertyBase
* property
, SetCallback callback
) {
151 MethodCall
method_call(kPropertiesInterface
, kPropertiesSet
);
152 MessageWriter
writer(&method_call
);
153 writer
.AppendString(interface());
154 writer
.AppendString(property
->name());
155 property
->AppendSetValueToWriter(&writer
);
157 DCHECK(object_proxy_
);
158 object_proxy_
->CallMethod(&method_call
,
159 ObjectProxy::TIMEOUT_USE_DEFAULT
,
160 base::Bind(&PropertySet::OnSet
,
166 void PropertySet::OnSet(PropertyBase
* property
, SetCallback callback
,
167 Response
* response
) {
168 LOG_IF(WARNING
, !response
) << property
->name() << ": Set: failed.";
169 if (!callback
.is_null())
170 callback
.Run(response
);
173 bool PropertySet::UpdatePropertiesFromReader(MessageReader
* reader
) {
175 MessageReader
array_reader(NULL
);
176 if (!reader
->PopArray(&array_reader
))
179 while (array_reader
.HasMoreData()) {
180 MessageReader
dict_entry_reader(NULL
);
181 if (array_reader
.PopDictEntry(&dict_entry_reader
))
182 UpdatePropertyFromReader(&dict_entry_reader
);
188 bool PropertySet::UpdatePropertyFromReader(MessageReader
* reader
) {
192 if (!reader
->PopString(&name
))
195 PropertiesMap::iterator it
= properties_map_
.find(name
);
196 if (it
== properties_map_
.end())
199 PropertyBase
* property
= it
->second
;
200 if (property
->PopValueFromReader(reader
)) {
201 NotifyPropertyChanged(name
);
209 void PropertySet::NotifyPropertyChanged(const std::string
& name
) {
210 if (!property_changed_callback_
.is_null())
211 property_changed_callback_
.Run(name
);
215 // Property<Byte> specialization.
219 Property
<uint8
>::Property() : value_(0) {
223 bool Property
<uint8
>::PopValueFromReader(MessageReader
* reader
) {
224 return reader
->PopVariantOfByte(&value_
);
228 void Property
<uint8
>::AppendSetValueToWriter(MessageWriter
* writer
) {
229 writer
->AppendVariantOfByte(set_value_
);
233 // Property<bool> specialization.
237 Property
<bool>::Property() : value_(false) {
241 bool Property
<bool>::PopValueFromReader(MessageReader
* reader
) {
242 return reader
->PopVariantOfBool(&value_
);
246 void Property
<bool>::AppendSetValueToWriter(MessageWriter
* writer
) {
247 writer
->AppendVariantOfBool(set_value_
);
251 // Property<int16> specialization.
255 Property
<int16
>::Property() : value_(0) {
259 bool Property
<int16
>::PopValueFromReader(MessageReader
* reader
) {
260 return reader
->PopVariantOfInt16(&value_
);
264 void Property
<int16
>::AppendSetValueToWriter(MessageWriter
* writer
) {
265 writer
->AppendVariantOfInt16(set_value_
);
269 // Property<uint16> specialization.
273 Property
<uint16
>::Property() : value_(0) {
277 bool Property
<uint16
>::PopValueFromReader(MessageReader
* reader
) {
278 return reader
->PopVariantOfUint16(&value_
);
282 void Property
<uint16
>::AppendSetValueToWriter(MessageWriter
* writer
) {
283 writer
->AppendVariantOfUint16(set_value_
);
287 // Property<int32> specialization.
291 Property
<int32
>::Property() : value_(0) {
295 bool Property
<int32
>::PopValueFromReader(MessageReader
* reader
) {
296 return reader
->PopVariantOfInt32(&value_
);
300 void Property
<int32
>::AppendSetValueToWriter(MessageWriter
* writer
) {
301 writer
->AppendVariantOfInt32(set_value_
);
305 // Property<uint32> specialization.
309 Property
<uint32
>::Property() : value_(0) {
313 bool Property
<uint32
>::PopValueFromReader(MessageReader
* reader
) {
314 return reader
->PopVariantOfUint32(&value_
);
318 void Property
<uint32
>::AppendSetValueToWriter(MessageWriter
* writer
) {
319 writer
->AppendVariantOfUint32(set_value_
);
323 // Property<int64> specialization.
327 Property
<int64
>::Property() : value_(0), set_value_(0) {
331 bool Property
<int64
>::PopValueFromReader(MessageReader
* reader
) {
332 return reader
->PopVariantOfInt64(&value_
);
336 void Property
<int64
>::AppendSetValueToWriter(MessageWriter
* writer
) {
337 writer
->AppendVariantOfInt64(set_value_
);
341 // Property<uint64> specialization.
345 Property
<uint64
>::Property() : value_(0) {
349 bool Property
<uint64
>::PopValueFromReader(MessageReader
* reader
) {
350 return reader
->PopVariantOfUint64(&value_
);
354 void Property
<uint64
>::AppendSetValueToWriter(MessageWriter
* writer
) {
355 writer
->AppendVariantOfUint64(set_value_
);
359 // Property<double> specialization.
363 Property
<double>::Property() : value_(0.0) {
367 bool Property
<double>::PopValueFromReader(MessageReader
* reader
) {
368 return reader
->PopVariantOfDouble(&value_
);
372 void Property
<double>::AppendSetValueToWriter(MessageWriter
* writer
) {
373 writer
->AppendVariantOfDouble(set_value_
);
377 // Property<std::string> specialization.
381 bool Property
<std::string
>::PopValueFromReader(MessageReader
* reader
) {
382 return reader
->PopVariantOfString(&value_
);
386 void Property
<std::string
>::AppendSetValueToWriter(MessageWriter
* writer
) {
387 writer
->AppendVariantOfString(set_value_
);
391 // Property<ObjectPath> specialization.
395 bool Property
<ObjectPath
>::PopValueFromReader(MessageReader
* reader
) {
396 return reader
->PopVariantOfObjectPath(&value_
);
400 void Property
<ObjectPath
>::AppendSetValueToWriter(MessageWriter
* writer
) {
401 writer
->AppendVariantOfObjectPath(set_value_
);
405 // Property<std::vector<std::string> > specialization.
409 bool Property
<std::vector
<std::string
> >::PopValueFromReader(
410 MessageReader
* reader
) {
411 MessageReader
variant_reader(NULL
);
412 if (!reader
->PopVariant(&variant_reader
))
416 return variant_reader
.PopArrayOfStrings(&value_
);
420 void Property
<std::vector
<std::string
> >::AppendSetValueToWriter(
421 MessageWriter
* writer
) {
422 MessageWriter
variant_writer(NULL
);
423 writer
->OpenVariant("as", &variant_writer
);
424 variant_writer
.AppendArrayOfStrings(set_value_
);
425 writer
->CloseContainer(&variant_writer
);
429 // Property<std::vector<ObjectPath> > specialization.
433 bool Property
<std::vector
<ObjectPath
> >::PopValueFromReader(
434 MessageReader
* reader
) {
435 MessageReader
variant_reader(NULL
);
436 if (!reader
->PopVariant(&variant_reader
))
440 return variant_reader
.PopArrayOfObjectPaths(&value_
);
444 void Property
<std::vector
<ObjectPath
> >::AppendSetValueToWriter(
445 MessageWriter
* writer
) {
446 MessageWriter
variant_writer(NULL
);
447 writer
->OpenVariant("ao", &variant_writer
);
448 variant_writer
.AppendArrayOfObjectPaths(set_value_
);
449 writer
->CloseContainer(&variant_writer
);