[MacViews] Fix TextfieldTest unit tests.
[chromium-blink-merge.git] / dbus / property.cc
blobdde061118bb8dc376f8818e188862c12a000dd31
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 PropertyBase::PropertyBase() : property_set_(nullptr), is_valid_(false) {}
23 PropertyBase::~PropertyBase() {}
25 void PropertyBase::Init(PropertySet* property_set, const std::string& name) {
26 DCHECK(!property_set_);
27 property_set_ = property_set;
28 is_valid_ = false;
29 name_ = name;
33 // PropertySet implementation.
36 PropertySet::PropertySet(
37 ObjectProxy* object_proxy,
38 const std::string& interface,
39 const PropertyChangedCallback& property_changed_callback)
40 : object_proxy_(object_proxy),
41 interface_(interface),
42 property_changed_callback_(property_changed_callback),
43 weak_ptr_factory_(this) {}
45 PropertySet::~PropertySet() {
48 void PropertySet::RegisterProperty(const std::string& name,
49 PropertyBase* property) {
50 property->Init(this, name);
51 properties_map_[name] = property;
54 void PropertySet::ConnectSignals() {
55 DCHECK(object_proxy_);
56 object_proxy_->ConnectToSignal(
57 kPropertiesInterface,
58 kPropertiesChanged,
59 base::Bind(&PropertySet::ChangedReceived,
60 weak_ptr_factory_.GetWeakPtr()),
61 base::Bind(&PropertySet::ChangedConnected,
62 weak_ptr_factory_.GetWeakPtr()));
66 void PropertySet::ChangedReceived(Signal* signal) {
67 DCHECK(signal);
68 MessageReader reader(signal);
70 std::string interface;
71 if (!reader.PopString(&interface)) {
72 LOG(WARNING) << "Property changed signal has wrong parameters: "
73 << "expected interface name: " << signal->ToString();
74 return;
77 if (interface != this->interface())
78 return;
80 if (!UpdatePropertiesFromReader(&reader)) {
81 LOG(WARNING) << "Property changed signal has wrong parameters: "
82 << "expected dictionary: " << signal->ToString();
85 if (!InvalidatePropertiesFromReader(&reader)) {
86 LOG(WARNING) << "Property changed signal has wrong parameters: "
87 << "expected array to invalidate: " << signal->ToString();
91 void PropertySet::ChangedConnected(const std::string& interface_name,
92 const std::string& signal_name,
93 bool success) {
94 LOG_IF(WARNING, !success) << "Failed to connect to " << signal_name
95 << "signal.";
99 void PropertySet::Get(PropertyBase* property, GetCallback callback) {
100 MethodCall method_call(kPropertiesInterface, kPropertiesGet);
101 MessageWriter writer(&method_call);
102 writer.AppendString(interface());
103 writer.AppendString(property->name());
105 DCHECK(object_proxy_);
106 object_proxy_->CallMethod(&method_call,
107 ObjectProxy::TIMEOUT_USE_DEFAULT,
108 base::Bind(&PropertySet::OnGet,
109 GetWeakPtr(),
110 property,
111 callback));
114 void PropertySet::OnGet(PropertyBase* property, GetCallback callback,
115 Response* response) {
116 if (!response) {
117 LOG(WARNING) << property->name() << ": Get: failed.";
118 return;
121 MessageReader reader(response);
122 if (property->PopValueFromReader(&reader)) {
123 property->set_valid(true);
124 NotifyPropertyChanged(property->name());
125 } else {
126 if (property->is_valid()) {
127 property->set_valid(false);
128 NotifyPropertyChanged(property->name());
132 if (!callback.is_null())
133 callback.Run(response);
136 void PropertySet::GetAll() {
137 MethodCall method_call(kPropertiesInterface, kPropertiesGetAll);
138 MessageWriter writer(&method_call);
139 writer.AppendString(interface());
141 DCHECK(object_proxy_);
142 object_proxy_->CallMethod(&method_call,
143 ObjectProxy::TIMEOUT_USE_DEFAULT,
144 base::Bind(&PropertySet::OnGetAll,
145 weak_ptr_factory_.GetWeakPtr()));
148 void PropertySet::OnGetAll(Response* response) {
149 if (!response) {
150 LOG(WARNING) << "GetAll request failed for: " << interface_;
151 return;
154 MessageReader reader(response);
155 if (!UpdatePropertiesFromReader(&reader)) {
156 LOG(WARNING) << "GetAll response has wrong parameters: "
157 << "expected dictionary: " << response->ToString();
161 void PropertySet::Set(PropertyBase* property, SetCallback callback) {
162 MethodCall method_call(kPropertiesInterface, kPropertiesSet);
163 MessageWriter writer(&method_call);
164 writer.AppendString(interface());
165 writer.AppendString(property->name());
166 property->AppendSetValueToWriter(&writer);
168 DCHECK(object_proxy_);
169 object_proxy_->CallMethod(&method_call,
170 ObjectProxy::TIMEOUT_USE_DEFAULT,
171 base::Bind(&PropertySet::OnSet,
172 GetWeakPtr(),
173 property,
174 callback));
177 void PropertySet::OnSet(PropertyBase* property,
178 SetCallback callback,
179 Response* response) {
180 LOG_IF(WARNING, !response) << property->name() << ": Set: failed.";
181 if (!callback.is_null())
182 callback.Run(response);
185 bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
186 DCHECK(reader);
187 MessageReader array_reader(NULL);
188 if (!reader->PopArray(&array_reader))
189 return false;
191 while (array_reader.HasMoreData()) {
192 MessageReader dict_entry_reader(NULL);
193 if (array_reader.PopDictEntry(&dict_entry_reader))
194 UpdatePropertyFromReader(&dict_entry_reader);
197 return true;
200 bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
201 DCHECK(reader);
203 std::string name;
204 if (!reader->PopString(&name))
205 return false;
207 PropertiesMap::iterator it = properties_map_.find(name);
208 if (it == properties_map_.end())
209 return false;
211 PropertyBase* property = it->second;
212 if (property->PopValueFromReader(reader)) {
213 property->set_valid(true);
214 NotifyPropertyChanged(name);
215 return true;
216 } else {
217 if (property->is_valid()) {
218 property->set_valid(false);
219 NotifyPropertyChanged(property->name());
221 return false;
225 bool PropertySet::InvalidatePropertiesFromReader(MessageReader* reader) {
226 DCHECK(reader);
227 MessageReader array_reader(NULL);
228 if (!reader->PopArray(&array_reader))
229 return false;
231 while (array_reader.HasMoreData()) {
232 std::string name;
233 if (!array_reader.PopString(&name))
234 return false;
236 PropertiesMap::iterator it = properties_map_.find(name);
237 if (it == properties_map_.end())
238 continue;
240 PropertyBase* property = it->second;
241 if (property->is_valid()) {
242 property->set_valid(false);
243 NotifyPropertyChanged(property->name());
247 return true;
250 void PropertySet::NotifyPropertyChanged(const std::string& name) {
251 if (!property_changed_callback_.is_null())
252 property_changed_callback_.Run(name);
256 // Property<Byte> specialization.
259 template <>
260 Property<uint8>::Property() : value_(0) {
263 template <>
264 bool Property<uint8>::PopValueFromReader(MessageReader* reader) {
265 return reader->PopVariantOfByte(&value_);
268 template <>
269 void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer) {
270 writer->AppendVariantOfByte(set_value_);
274 // Property<bool> specialization.
277 template <>
278 Property<bool>::Property() : value_(false) {
281 template <>
282 bool Property<bool>::PopValueFromReader(MessageReader* reader) {
283 return reader->PopVariantOfBool(&value_);
286 template <>
287 void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
288 writer->AppendVariantOfBool(set_value_);
292 // Property<int16> specialization.
295 template <>
296 Property<int16>::Property() : value_(0) {
299 template <>
300 bool Property<int16>::PopValueFromReader(MessageReader* reader) {
301 return reader->PopVariantOfInt16(&value_);
304 template <>
305 void Property<int16>::AppendSetValueToWriter(MessageWriter* writer) {
306 writer->AppendVariantOfInt16(set_value_);
310 // Property<uint16> specialization.
313 template <>
314 Property<uint16>::Property() : value_(0) {
317 template <>
318 bool Property<uint16>::PopValueFromReader(MessageReader* reader) {
319 return reader->PopVariantOfUint16(&value_);
322 template <>
323 void Property<uint16>::AppendSetValueToWriter(MessageWriter* writer) {
324 writer->AppendVariantOfUint16(set_value_);
328 // Property<int32> specialization.
331 template <>
332 Property<int32>::Property() : value_(0) {
335 template <>
336 bool Property<int32>::PopValueFromReader(MessageReader* reader) {
337 return reader->PopVariantOfInt32(&value_);
340 template <>
341 void Property<int32>::AppendSetValueToWriter(MessageWriter* writer) {
342 writer->AppendVariantOfInt32(set_value_);
346 // Property<uint32> specialization.
349 template <>
350 Property<uint32>::Property() : value_(0) {
353 template <>
354 bool Property<uint32>::PopValueFromReader(MessageReader* reader) {
355 return reader->PopVariantOfUint32(&value_);
358 template <>
359 void Property<uint32>::AppendSetValueToWriter(MessageWriter* writer) {
360 writer->AppendVariantOfUint32(set_value_);
364 // Property<int64> specialization.
367 template <>
368 Property<int64>::Property() : value_(0), set_value_(0) {
371 template <>
372 bool Property<int64>::PopValueFromReader(MessageReader* reader) {
373 return reader->PopVariantOfInt64(&value_);
376 template <>
377 void Property<int64>::AppendSetValueToWriter(MessageWriter* writer) {
378 writer->AppendVariantOfInt64(set_value_);
382 // Property<uint64> specialization.
385 template <>
386 Property<uint64>::Property() : value_(0) {
389 template <>
390 bool Property<uint64>::PopValueFromReader(MessageReader* reader) {
391 return reader->PopVariantOfUint64(&value_);
394 template <>
395 void Property<uint64>::AppendSetValueToWriter(MessageWriter* writer) {
396 writer->AppendVariantOfUint64(set_value_);
400 // Property<double> specialization.
403 template <>
404 Property<double>::Property() : value_(0.0) {
407 template <>
408 bool Property<double>::PopValueFromReader(MessageReader* reader) {
409 return reader->PopVariantOfDouble(&value_);
412 template <>
413 void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
414 writer->AppendVariantOfDouble(set_value_);
418 // Property<std::string> specialization.
421 template <>
422 bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
423 return reader->PopVariantOfString(&value_);
426 template <>
427 void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
428 writer->AppendVariantOfString(set_value_);
432 // Property<ObjectPath> specialization.
435 template <>
436 bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
437 return reader->PopVariantOfObjectPath(&value_);
440 template <>
441 void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
442 writer->AppendVariantOfObjectPath(set_value_);
446 // Property<std::vector<std::string> > specialization.
449 template <>
450 bool Property<std::vector<std::string> >::PopValueFromReader(
451 MessageReader* reader) {
452 MessageReader variant_reader(NULL);
453 if (!reader->PopVariant(&variant_reader))
454 return false;
456 value_.clear();
457 return variant_reader.PopArrayOfStrings(&value_);
460 template <>
461 void Property<std::vector<std::string> >::AppendSetValueToWriter(
462 MessageWriter* writer) {
463 MessageWriter variant_writer(NULL);
464 writer->OpenVariant("as", &variant_writer);
465 variant_writer.AppendArrayOfStrings(set_value_);
466 writer->CloseContainer(&variant_writer);
470 // Property<std::vector<ObjectPath> > specialization.
473 template <>
474 bool Property<std::vector<ObjectPath> >::PopValueFromReader(
475 MessageReader* reader) {
476 MessageReader variant_reader(NULL);
477 if (!reader->PopVariant(&variant_reader))
478 return false;
480 value_.clear();
481 return variant_reader.PopArrayOfObjectPaths(&value_);
484 template <>
485 void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
486 MessageWriter* writer) {
487 MessageWriter variant_writer(NULL);
488 writer->OpenVariant("ao", &variant_writer);
489 variant_writer.AppendArrayOfObjectPaths(set_value_);
490 writer->CloseContainer(&variant_writer);
494 // Property<std::vector<uint8> > specialization.
497 template <>
498 bool Property<std::vector<uint8> >::PopValueFromReader(MessageReader* reader) {
499 MessageReader variant_reader(NULL);
500 if (!reader->PopVariant(&variant_reader))
501 return false;
503 value_.clear();
504 const uint8* bytes = NULL;
505 size_t length = 0;
506 if (!variant_reader.PopArrayOfBytes(&bytes, &length))
507 return false;
508 value_.assign(bytes, bytes + length);
509 return true;
512 template <>
513 void Property<std::vector<uint8> >::AppendSetValueToWriter(
514 MessageWriter* writer) {
515 MessageWriter variant_writer(NULL);
516 writer->OpenVariant("ay", &variant_writer);
517 variant_writer.AppendArrayOfBytes(set_value_.data(), set_value_.size());
518 writer->CloseContainer(&variant_writer);
522 // Property<std::map<std::string, std::string>> specialization.
525 template <>
526 bool Property<std::map<std::string, std::string>>::PopValueFromReader(
527 MessageReader* reader) {
528 MessageReader variant_reader(NULL);
529 MessageReader array_reader(NULL);
530 if (!reader->PopVariant(&variant_reader) ||
531 !variant_reader.PopArray(&array_reader))
532 return false;
533 value_.clear();
534 while (array_reader.HasMoreData()) {
535 dbus::MessageReader dict_entry_reader(NULL);
536 if (!array_reader.PopDictEntry(&dict_entry_reader))
537 return false;
538 std::string key;
539 std::string value;
540 if (!dict_entry_reader.PopString(&key) ||
541 !dict_entry_reader.PopString(&value))
542 return false;
543 value_[key] = value;
545 return true;
548 template <>
549 void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
550 MessageWriter* writer) {
551 MessageWriter variant_writer(NULL);
552 MessageWriter dict_writer(NULL);
553 writer->OpenVariant("a{ss}", &variant_writer);
554 variant_writer.OpenArray("{ss}", &dict_writer);
555 for (const auto& pair : set_value_) {
556 dbus::MessageWriter entry_writer(NULL);
557 dict_writer.OpenDictEntry(&entry_writer);
558 entry_writer.AppendString(pair.first);
559 entry_writer.AppendString(pair.second);
560 dict_writer.CloseContainer(&entry_writer);
562 variant_writer.CloseContainer(&dict_writer);
563 writer->CloseContainer(&variant_writer);
567 // Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
568 // specialization.
571 template <>
572 bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
573 PopValueFromReader(MessageReader* reader) {
574 MessageReader variant_reader(NULL);
575 MessageReader array_reader(NULL);
576 if (!reader->PopVariant(&variant_reader) ||
577 !variant_reader.PopArray(&array_reader))
578 return false;
580 value_.clear();
581 while (array_reader.HasMoreData()) {
582 dbus::MessageReader struct_reader(NULL);
583 if (!array_reader.PopStruct(&struct_reader))
584 return false;
586 std::pair<std::vector<uint8_t>, uint16_t> entry;
587 const uint8* bytes = NULL;
588 size_t length = 0;
589 if (!struct_reader.PopArrayOfBytes(&bytes, &length))
590 return false;
591 entry.first.assign(bytes, bytes + length);
592 if (!struct_reader.PopUint16(&entry.second))
593 return false;
594 value_.push_back(entry);
596 return true;
599 template <>
600 void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
601 AppendSetValueToWriter(MessageWriter* writer) {
602 MessageWriter variant_writer(NULL);
603 MessageWriter array_writer(NULL);
604 writer->OpenVariant("a(ayq)", &variant_writer);
605 variant_writer.OpenArray("(ayq)", &array_writer);
606 for (const auto& pair : set_value_) {
607 dbus::MessageWriter struct_writer(nullptr);
608 array_writer.OpenStruct(&struct_writer);
609 struct_writer.AppendArrayOfBytes(std::get<0>(pair).data(),
610 std::get<0>(pair).size());
611 struct_writer.AppendUint16(std::get<1>(pair));
612 array_writer.CloseContainer(&struct_writer);
614 variant_writer.CloseContainer(&array_writer);
615 writer->CloseContainer(&variant_writer);
618 template class Property<uint8>;
619 template class Property<bool>;
620 template class Property<int16>;
621 template class Property<uint16>;
622 template class Property<int32>;
623 template class Property<uint32>;
624 template class Property<int64>;
625 template class Property<uint64>;
626 template class Property<double>;
627 template class Property<std::string>;
628 template class Property<ObjectPath>;
629 template class Property<std::vector<std::string> >;
630 template class Property<std::vector<ObjectPath> >;
631 template class Property<std::vector<uint8> >;
632 template class Property<std::map<std::string, std::string>>;
633 template class Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
635 } // namespace dbus