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(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(
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
) {
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();
72 if (interface
!= this->interface())
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
,
89 LOG_IF(WARNING
, !success
) << "Failed to connect to " << signal_name
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
) {
108 LOG(WARNING
) << "GetAll request failed.";
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
) {
122 MessageReader
array_reader(NULL
);
123 if (!reader
->PopArray(&array_reader
))
126 while (array_reader
.HasMoreData()) {
127 MessageReader
dict_entry_reader(NULL
);
128 if (!array_reader
.PopDictEntry(&dict_entry_reader
))
131 if (!UpdatePropertyFromReader(&dict_entry_reader
))
138 bool PropertySet::UpdatePropertyFromReader(MessageReader
* reader
) {
142 if (!reader
->PopString(&name
))
145 PropertiesMap::iterator it
= properties_map_
.find(name
);
146 if (it
== properties_map_
.end())
149 PropertyBase
* property
= it
->second
;
150 if (property
->PopValueFromReader(reader
)) {
151 NotifyPropertyChanged(name
);
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.
169 Property
<uint8
>::Property() : value_(0),
170 weak_ptr_factory_(this) {
174 bool Property
<uint8
>::PopValueFromReader(MessageReader
* reader
) {
175 return reader
->PopVariantOfByte(&value_
);
179 void Property
<uint8
>::AppendToWriter(MessageWriter
* writer
,
180 const uint8
& value
) {
181 writer
->AppendVariantOfByte(value
);
185 // Property<bool> specialization.
189 Property
<bool>::Property() : value_(false),
190 weak_ptr_factory_(this) {
194 bool Property
<bool>::PopValueFromReader(MessageReader
* reader
) {
195 return reader
->PopVariantOfBool(&value_
);
199 void Property
<bool>::AppendToWriter(MessageWriter
* writer
,
201 writer
->AppendVariantOfBool(value
);
205 // Property<int16> specialization.
209 Property
<int16
>::Property() : value_(0),
210 weak_ptr_factory_(this) {
214 bool Property
<int16
>::PopValueFromReader(MessageReader
* reader
) {
215 return reader
->PopVariantOfInt16(&value_
);
219 void Property
<int16
>::AppendToWriter(MessageWriter
* writer
,
220 const int16
& value
) {
221 writer
->AppendVariantOfInt16(value
);
225 // Property<uint16> specialization.
229 Property
<uint16
>::Property() : value_(0),
230 weak_ptr_factory_(this) {
234 bool Property
<uint16
>::PopValueFromReader(MessageReader
* reader
) {
235 return reader
->PopVariantOfUint16(&value_
);
239 void Property
<uint16
>::AppendToWriter(MessageWriter
* writer
,
240 const uint16
& value
) {
241 writer
->AppendVariantOfUint16(value
);
245 // Property<int32> specialization.
249 Property
<int32
>::Property() : value_(0),
250 weak_ptr_factory_(this) {
254 bool Property
<int32
>::PopValueFromReader(MessageReader
* reader
) {
255 return reader
->PopVariantOfInt32(&value_
);
259 void Property
<int32
>::AppendToWriter(MessageWriter
* writer
,
260 const int32
& value
) {
261 writer
->AppendVariantOfInt32(value
);
265 // Property<uint32> specialization.
269 Property
<uint32
>::Property() : value_(0),
270 weak_ptr_factory_(this) {
274 bool Property
<uint32
>::PopValueFromReader(MessageReader
* reader
) {
275 return reader
->PopVariantOfUint32(&value_
);
279 void Property
<uint32
>::AppendToWriter(MessageWriter
* writer
,
280 const uint32
& value
) {
281 writer
->AppendVariantOfUint32(value
);
285 // Property<int64> specialization.
289 Property
<int64
>::Property() : value_(0),
290 weak_ptr_factory_(this) {
294 bool Property
<int64
>::PopValueFromReader(MessageReader
* reader
) {
295 return reader
->PopVariantOfInt64(&value_
);
299 void Property
<int64
>::AppendToWriter(MessageWriter
* writer
,
300 const int64
& value
) {
301 writer
->AppendVariantOfInt64(value
);
305 // Property<uint64> specialization.
309 Property
<uint64
>::Property() : value_(0),
310 weak_ptr_factory_(this) {
314 bool Property
<uint64
>::PopValueFromReader(MessageReader
* reader
) {
315 return reader
->PopVariantOfUint64(&value_
);
319 void Property
<uint64
>::AppendToWriter(MessageWriter
* writer
,
320 const uint64
& value
) {
321 writer
->AppendVariantOfUint64(value
);
325 // Property<double> specialization.
329 Property
<double>::Property() : value_(0.0),
330 weak_ptr_factory_(this) {
334 bool Property
<double>::PopValueFromReader(MessageReader
* reader
) {
335 return reader
->PopVariantOfDouble(&value_
);
339 void Property
<double>::AppendToWriter(MessageWriter
* writer
,
340 const double& value
) {
341 writer
->AppendVariantOfDouble(value
);
345 // Property<std::string> specialization.
349 bool Property
<std::string
>::PopValueFromReader(MessageReader
* reader
) {
350 return reader
->PopVariantOfString(&value_
);
354 void Property
<std::string
>::AppendToWriter(MessageWriter
* writer
,
355 const std::string
& value
) {
356 writer
->AppendVariantOfString(value
);
360 // Property<ObjectPath> specialization.
364 bool Property
<ObjectPath
>::PopValueFromReader(MessageReader
* reader
) {
365 return reader
->PopVariantOfObjectPath(&value_
);
369 void Property
<ObjectPath
>::AppendToWriter(MessageWriter
* writer
,
370 const ObjectPath
& value
) {
371 writer
->AppendVariantOfObjectPath(value
);
375 // Property<std::vector<std::string> > specialization.
379 bool Property
<std::vector
<std::string
> >::PopValueFromReader(
380 MessageReader
* reader
) {
381 MessageReader
variant_reader(NULL
);
382 if (!reader
->PopVariant(&variant_reader
))
385 return variant_reader
.PopArrayOfStrings(&value_
);
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.
403 bool Property
<std::vector
<ObjectPath
> >::PopValueFromReader(
404 MessageReader
* reader
) {
405 MessageReader
variant_reader(NULL
);
406 if (!reader
->PopVariant(&variant_reader
))
409 return variant_reader
.PopArrayOfObjectPaths(&value_
);
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
);