Updates the layout text when multiline property has been changed.
[chromium-blink-merge.git] / dbus / property.cc
blob0e912f34daa20ec377b04ed7f302b61d6f58b242
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(
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(
53 kPropertiesInterface,
54 kPropertiesChanged,
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) {
63 DCHECK(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();
70 return;
73 if (interface != this->interface())
74 return;
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,
89 bool success) {
90 LOG_IF(WARNING, !success) << "Failed to connect to " << signal_name
91 << "signal.";
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,
105 GetWeakPtr(),
106 property,
107 callback));
110 void PropertySet::OnGet(PropertyBase* property, GetCallback callback,
111 Response* response) {
112 if (!response) {
113 LOG(WARNING) << property->name() << ": Get: failed.";
114 return;
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) {
138 if (!response) {
139 LOG(WARNING) << "GetAll request failed for: " << interface_;
140 return;
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,
161 GetWeakPtr(),
162 property,
163 callback));
166 void PropertySet::OnSet(PropertyBase* property,
167 SetCallback callback,
168 Response* response) {
169 LOG_IF(WARNING, !response) << property->name() << ": Set: failed.";
170 if (!callback.is_null())
171 callback.Run(response);
174 bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
175 DCHECK(reader);
176 MessageReader array_reader(NULL);
177 if (!reader->PopArray(&array_reader))
178 return false;
180 while (array_reader.HasMoreData()) {
181 MessageReader dict_entry_reader(NULL);
182 if (array_reader.PopDictEntry(&dict_entry_reader))
183 UpdatePropertyFromReader(&dict_entry_reader);
186 return true;
189 bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
190 DCHECK(reader);
192 std::string name;
193 if (!reader->PopString(&name))
194 return false;
196 PropertiesMap::iterator it = properties_map_.find(name);
197 if (it == properties_map_.end())
198 return false;
200 PropertyBase* property = it->second;
201 if (property->PopValueFromReader(reader)) {
202 NotifyPropertyChanged(name);
203 return true;
204 } else {
205 return false;
210 void PropertySet::NotifyPropertyChanged(const std::string& name) {
211 if (!property_changed_callback_.is_null())
212 property_changed_callback_.Run(name);
216 // Property<Byte> specialization.
219 template <>
220 Property<uint8>::Property() : value_(0) {
223 template <>
224 bool Property<uint8>::PopValueFromReader(MessageReader* reader) {
225 return reader->PopVariantOfByte(&value_);
228 template <>
229 void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer) {
230 writer->AppendVariantOfByte(set_value_);
234 // Property<bool> specialization.
237 template <>
238 Property<bool>::Property() : value_(false) {
241 template <>
242 bool Property<bool>::PopValueFromReader(MessageReader* reader) {
243 return reader->PopVariantOfBool(&value_);
246 template <>
247 void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
248 writer->AppendVariantOfBool(set_value_);
252 // Property<int16> specialization.
255 template <>
256 Property<int16>::Property() : value_(0) {
259 template <>
260 bool Property<int16>::PopValueFromReader(MessageReader* reader) {
261 return reader->PopVariantOfInt16(&value_);
264 template <>
265 void Property<int16>::AppendSetValueToWriter(MessageWriter* writer) {
266 writer->AppendVariantOfInt16(set_value_);
270 // Property<uint16> specialization.
273 template <>
274 Property<uint16>::Property() : value_(0) {
277 template <>
278 bool Property<uint16>::PopValueFromReader(MessageReader* reader) {
279 return reader->PopVariantOfUint16(&value_);
282 template <>
283 void Property<uint16>::AppendSetValueToWriter(MessageWriter* writer) {
284 writer->AppendVariantOfUint16(set_value_);
288 // Property<int32> specialization.
291 template <>
292 Property<int32>::Property() : value_(0) {
295 template <>
296 bool Property<int32>::PopValueFromReader(MessageReader* reader) {
297 return reader->PopVariantOfInt32(&value_);
300 template <>
301 void Property<int32>::AppendSetValueToWriter(MessageWriter* writer) {
302 writer->AppendVariantOfInt32(set_value_);
306 // Property<uint32> specialization.
309 template <>
310 Property<uint32>::Property() : value_(0) {
313 template <>
314 bool Property<uint32>::PopValueFromReader(MessageReader* reader) {
315 return reader->PopVariantOfUint32(&value_);
318 template <>
319 void Property<uint32>::AppendSetValueToWriter(MessageWriter* writer) {
320 writer->AppendVariantOfUint32(set_value_);
324 // Property<int64> specialization.
327 template <>
328 Property<int64>::Property() : value_(0), set_value_(0) {
331 template <>
332 bool Property<int64>::PopValueFromReader(MessageReader* reader) {
333 return reader->PopVariantOfInt64(&value_);
336 template <>
337 void Property<int64>::AppendSetValueToWriter(MessageWriter* writer) {
338 writer->AppendVariantOfInt64(set_value_);
342 // Property<uint64> specialization.
345 template <>
346 Property<uint64>::Property() : value_(0) {
349 template <>
350 bool Property<uint64>::PopValueFromReader(MessageReader* reader) {
351 return reader->PopVariantOfUint64(&value_);
354 template <>
355 void Property<uint64>::AppendSetValueToWriter(MessageWriter* writer) {
356 writer->AppendVariantOfUint64(set_value_);
360 // Property<double> specialization.
363 template <>
364 Property<double>::Property() : value_(0.0) {
367 template <>
368 bool Property<double>::PopValueFromReader(MessageReader* reader) {
369 return reader->PopVariantOfDouble(&value_);
372 template <>
373 void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
374 writer->AppendVariantOfDouble(set_value_);
378 // Property<std::string> specialization.
381 template <>
382 bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
383 return reader->PopVariantOfString(&value_);
386 template <>
387 void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
388 writer->AppendVariantOfString(set_value_);
392 // Property<ObjectPath> specialization.
395 template <>
396 bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
397 return reader->PopVariantOfObjectPath(&value_);
400 template <>
401 void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
402 writer->AppendVariantOfObjectPath(set_value_);
406 // Property<std::vector<std::string> > specialization.
409 template <>
410 bool Property<std::vector<std::string> >::PopValueFromReader(
411 MessageReader* reader) {
412 MessageReader variant_reader(NULL);
413 if (!reader->PopVariant(&variant_reader))
414 return false;
416 value_.clear();
417 return variant_reader.PopArrayOfStrings(&value_);
420 template <>
421 void Property<std::vector<std::string> >::AppendSetValueToWriter(
422 MessageWriter* writer) {
423 MessageWriter variant_writer(NULL);
424 writer->OpenVariant("as", &variant_writer);
425 variant_writer.AppendArrayOfStrings(set_value_);
426 writer->CloseContainer(&variant_writer);
430 // Property<std::vector<ObjectPath> > specialization.
433 template <>
434 bool Property<std::vector<ObjectPath> >::PopValueFromReader(
435 MessageReader* reader) {
436 MessageReader variant_reader(NULL);
437 if (!reader->PopVariant(&variant_reader))
438 return false;
440 value_.clear();
441 return variant_reader.PopArrayOfObjectPaths(&value_);
444 template <>
445 void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
446 MessageWriter* writer) {
447 MessageWriter variant_writer(NULL);
448 writer->OpenVariant("ao", &variant_writer);
449 variant_writer.AppendArrayOfObjectPaths(set_value_);
450 writer->CloseContainer(&variant_writer);
454 // Property<std::vector<uint8> > specialization.
457 template <>
458 bool Property<std::vector<uint8> >::PopValueFromReader(MessageReader* reader) {
459 MessageReader variant_reader(NULL);
460 if (!reader->PopVariant(&variant_reader))
461 return false;
463 value_.clear();
464 const uint8* bytes = NULL;
465 size_t length = 0;
466 if (!variant_reader.PopArrayOfBytes(&bytes, &length))
467 return false;
468 value_.assign(bytes, bytes + length);
469 return true;
472 template <>
473 void Property<std::vector<uint8> >::AppendSetValueToWriter(
474 MessageWriter* writer) {
475 MessageWriter variant_writer(NULL);
476 writer->OpenVariant("ay", &variant_writer);
477 variant_writer.AppendArrayOfBytes(set_value_.data(), set_value_.size());
478 writer->CloseContainer(&variant_writer);
482 // Property<std::map<std::string, std::string>> specialization.
485 template <>
486 bool Property<std::map<std::string, std::string>>::PopValueFromReader(
487 MessageReader* reader) {
488 MessageReader variant_reader(NULL);
489 MessageReader array_reader(NULL);
490 if (!reader->PopVariant(&variant_reader) ||
491 !variant_reader.PopArray(&array_reader))
492 return false;
493 value_.clear();
494 while (array_reader.HasMoreData()) {
495 dbus::MessageReader dict_entry_reader(NULL);
496 if (!array_reader.PopDictEntry(&dict_entry_reader))
497 return false;
498 std::string key;
499 std::string value;
500 if (!dict_entry_reader.PopString(&key) ||
501 !dict_entry_reader.PopString(&value))
502 return false;
503 value_[key] = value;
505 return true;
508 template <>
509 void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
510 MessageWriter* writer) {
511 MessageWriter variant_writer(NULL);
512 MessageWriter dict_writer(NULL);
513 writer->OpenVariant("a{ss}", &variant_writer);
514 variant_writer.OpenArray("{ss}", &dict_writer);
515 for (const auto& pair : set_value_) {
516 dbus::MessageWriter entry_writer(NULL);
517 dict_writer.OpenDictEntry(&entry_writer);
518 entry_writer.AppendString(pair.first);
519 entry_writer.AppendString(pair.second);
520 dict_writer.CloseContainer(&entry_writer);
522 variant_writer.CloseContainer(&dict_writer);
523 writer->CloseContainer(&variant_writer);
527 // Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
528 // specialization.
531 template <>
532 bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
533 PopValueFromReader(MessageReader* reader) {
534 MessageReader variant_reader(NULL);
535 MessageReader array_reader(NULL);
536 if (!reader->PopVariant(&variant_reader) ||
537 !variant_reader.PopArray(&array_reader))
538 return false;
540 value_.clear();
541 while (array_reader.HasMoreData()) {
542 dbus::MessageReader struct_reader(NULL);
543 if (!array_reader.PopStruct(&struct_reader))
544 return false;
546 std::pair<std::vector<uint8_t>, uint16_t> entry;
547 const uint8* bytes = NULL;
548 size_t length = 0;
549 if (!struct_reader.PopArrayOfBytes(&bytes, &length))
550 return false;
551 entry.first.assign(bytes, bytes + length);
552 if (!struct_reader.PopUint16(&entry.second))
553 return false;
554 value_.push_back(entry);
556 return true;
559 template <>
560 void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
561 AppendSetValueToWriter(MessageWriter* writer) {
562 MessageWriter variant_writer(NULL);
563 MessageWriter array_writer(NULL);
564 writer->OpenVariant("a(ayq)", &variant_writer);
565 variant_writer.OpenArray("(ayq)", &array_writer);
566 for (const auto& pair : set_value_) {
567 dbus::MessageWriter struct_writer(nullptr);
568 array_writer.OpenStruct(&struct_writer);
569 struct_writer.AppendArrayOfBytes(std::get<0>(pair).data(),
570 std::get<0>(pair).size());
571 struct_writer.AppendUint16(std::get<1>(pair));
572 array_writer.CloseContainer(&struct_writer);
574 variant_writer.CloseContainer(&array_writer);
575 writer->CloseContainer(&variant_writer);
578 template class Property<uint8>;
579 template class Property<bool>;
580 template class Property<int16>;
581 template class Property<uint16>;
582 template class Property<int32>;
583 template class Property<uint32>;
584 template class Property<int64>;
585 template class Property<uint64>;
586 template class Property<double>;
587 template class Property<std::string>;
588 template class Property<ObjectPath>;
589 template class Property<std::vector<std::string> >;
590 template class Property<std::vector<ObjectPath> >;
591 template class Property<std::vector<uint8> >;
592 template class Property<std::map<std::string, std::string>>;
593 template class Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
595 } // namespace dbus