blob: 9475a0728a6cca7e4de360caa10333593a4bda44 [file] [log] [blame]
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +09001// 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.
4
5#include "dbus/property.h"
6
7#include "base/basictypes.h"
8#include "base/bind.h"
9#include "base/logging.h"
10
11#include "dbus/message.h"
12#include "dbus/object_path.h"
13#include "dbus/object_proxy.h"
14
15namespace dbus {
16
17//
18// PropertyBase implementation.
19//
20
21void PropertyBase::Init(PropertySet* property_set, const std::string& name) {
22 DCHECK(!property_set_);
23 property_set_ = property_set;
24 name_ = name;
25}
26
27
28//
29// PropertySet implementation.
30//
31
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +090032PropertySet::PropertySet(
33 ObjectProxy* object_proxy,
34 const std::string& interface,
35 const PropertyChangedCallback& property_changed_callback)
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090036 : object_proxy_(object_proxy),
37 interface_(interface),
38 property_changed_callback_(property_changed_callback),
39 weak_ptr_factory_(this) {}
40
41PropertySet::~PropertySet() {
42}
43
44void PropertySet::RegisterProperty(const std::string& name,
45 PropertyBase* property) {
46 property->Init(this, name);
47 properties_map_[name] = property;
48}
49
50void 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()));
59}
60
61
62void PropertySet::ChangedReceived(Signal* signal) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090063 DCHECK(signal);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090064 MessageReader reader(signal);
65
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;
71 }
72
73 if (interface != this->interface())
74 return;
75
76 if (!UpdatePropertiesFromReader(&reader)) {
77 LOG(WARNING) << "Property changed signal has wrong parameters: "
78 << "expected dictionary: " << signal->ToString();
79 }
80
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.
85}
86
87void 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.";
92}
93
94
keybuk@chromium.org56028ac2012-06-29 03:43:30 +090095void 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());
100
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));
108}
109
110void PropertySet::OnGet(PropertyBase* property, GetCallback callback,
111 Response* response) {
112 if (!response) {
113 LOG(WARNING) << property->name() << ": Get: failed.";
114 return;
115 }
116
117 MessageReader reader(response);
118 if (property->PopValueFromReader(&reader))
119 NotifyPropertyChanged(property->name());
120
121 if (!callback.is_null())
122 callback.Run(response);
123}
124
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900125void PropertySet::GetAll() {
126 MethodCall method_call(kPropertiesInterface, kPropertiesGetAll);
127 MessageWriter writer(&method_call);
128 writer.AppendString(interface());
129
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()));
135}
136
137void PropertySet::OnGetAll(Response* response) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900138 if (!response) {
stevenjb@chromium.orgfa639cc2014-07-17 14:03:53 +0900139 LOG(WARNING) << "GetAll request failed for: " << interface_;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900140 return;
141 }
142
143 MessageReader reader(response);
144 if (!UpdatePropertiesFromReader(&reader)) {
145 LOG(WARNING) << "GetAll response has wrong parameters: "
146 << "expected dictionary: " << response->ToString();
147 }
148}
149
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900150void 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);
156
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));
164}
165
stevenjb@chromium.orgfa639cc2014-07-17 14:03:53 +0900166void PropertySet::OnSet(PropertyBase* property,
167 SetCallback callback,
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900168 Response* response) {
169 LOG_IF(WARNING, !response) << property->name() << ": Set: failed.";
170 if (!callback.is_null())
171 callback.Run(response);
172}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900173
174bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
175 DCHECK(reader);
176 MessageReader array_reader(NULL);
177 if (!reader->PopArray(&array_reader))
178 return false;
179
180 while (array_reader.HasMoreData()) {
181 MessageReader dict_entry_reader(NULL);
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900182 if (array_reader.PopDictEntry(&dict_entry_reader))
183 UpdatePropertyFromReader(&dict_entry_reader);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900184 }
185
186 return true;
187}
188
189bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
190 DCHECK(reader);
191
192 std::string name;
193 if (!reader->PopString(&name))
194 return false;
195
196 PropertiesMap::iterator it = properties_map_.find(name);
197 if (it == properties_map_.end())
198 return false;
199
200 PropertyBase* property = it->second;
201 if (property->PopValueFromReader(reader)) {
202 NotifyPropertyChanged(name);
203 return true;
204 } else {
205 return false;
206 }
207}
208
209
210void PropertySet::NotifyPropertyChanged(const std::string& name) {
211 if (!property_changed_callback_.is_null())
212 property_changed_callback_.Run(name);
213}
214
215//
216// Property<Byte> specialization.
217//
218
219template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900220Property<uint8>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900221}
222
223template <>
224bool Property<uint8>::PopValueFromReader(MessageReader* reader) {
225 return reader->PopVariantOfByte(&value_);
226}
227
228template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900229void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer) {
230 writer->AppendVariantOfByte(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900231}
232
233//
234// Property<bool> specialization.
235//
236
237template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900238Property<bool>::Property() : value_(false) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900239}
240
241template <>
242bool Property<bool>::PopValueFromReader(MessageReader* reader) {
243 return reader->PopVariantOfBool(&value_);
244}
245
246template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900247void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
248 writer->AppendVariantOfBool(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900249}
250
251//
252// Property<int16> specialization.
253//
254
255template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900256Property<int16>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900257}
258
259template <>
260bool Property<int16>::PopValueFromReader(MessageReader* reader) {
261 return reader->PopVariantOfInt16(&value_);
262}
263
264template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900265void Property<int16>::AppendSetValueToWriter(MessageWriter* writer) {
266 writer->AppendVariantOfInt16(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900267}
268
269//
270// Property<uint16> specialization.
271//
272
273template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900274Property<uint16>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900275}
276
277template <>
278bool Property<uint16>::PopValueFromReader(MessageReader* reader) {
279 return reader->PopVariantOfUint16(&value_);
280}
281
282template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900283void Property<uint16>::AppendSetValueToWriter(MessageWriter* writer) {
284 writer->AppendVariantOfUint16(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900285}
286
287//
288// Property<int32> specialization.
289//
290
291template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900292Property<int32>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900293}
294
295template <>
296bool Property<int32>::PopValueFromReader(MessageReader* reader) {
297 return reader->PopVariantOfInt32(&value_);
298}
299
300template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900301void Property<int32>::AppendSetValueToWriter(MessageWriter* writer) {
302 writer->AppendVariantOfInt32(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900303}
304
305//
306// Property<uint32> specialization.
307//
308
309template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900310Property<uint32>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900311}
312
313template <>
314bool Property<uint32>::PopValueFromReader(MessageReader* reader) {
315 return reader->PopVariantOfUint32(&value_);
316}
317
318template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900319void Property<uint32>::AppendSetValueToWriter(MessageWriter* writer) {
320 writer->AppendVariantOfUint32(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900321}
322
323//
324// Property<int64> specialization.
325//
326
327template <>
jhawkins@chromium.org9ef14692012-07-26 07:08:27 +0900328Property<int64>::Property() : value_(0), set_value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900329}
330
331template <>
332bool Property<int64>::PopValueFromReader(MessageReader* reader) {
333 return reader->PopVariantOfInt64(&value_);
334}
335
336template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900337void Property<int64>::AppendSetValueToWriter(MessageWriter* writer) {
338 writer->AppendVariantOfInt64(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900339}
340
341//
342// Property<uint64> specialization.
343//
344
345template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900346Property<uint64>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900347}
348
349template <>
350bool Property<uint64>::PopValueFromReader(MessageReader* reader) {
351 return reader->PopVariantOfUint64(&value_);
352}
353
354template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900355void Property<uint64>::AppendSetValueToWriter(MessageWriter* writer) {
356 writer->AppendVariantOfUint64(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900357}
358
359//
360// Property<double> specialization.
361//
362
363template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900364Property<double>::Property() : value_(0.0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900365}
366
367template <>
368bool Property<double>::PopValueFromReader(MessageReader* reader) {
369 return reader->PopVariantOfDouble(&value_);
370}
371
372template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900373void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
374 writer->AppendVariantOfDouble(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900375}
376
377//
378// Property<std::string> specialization.
379//
380
381template <>
382bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
383 return reader->PopVariantOfString(&value_);
384}
385
386template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900387void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
388 writer->AppendVariantOfString(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900389}
390
391//
392// Property<ObjectPath> specialization.
393//
394
395template <>
396bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
397 return reader->PopVariantOfObjectPath(&value_);
398}
399
400template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900401void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
402 writer->AppendVariantOfObjectPath(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900403}
404
405//
406// Property<std::vector<std::string> > specialization.
407//
408
409template <>
410bool Property<std::vector<std::string> >::PopValueFromReader(
411 MessageReader* reader) {
412 MessageReader variant_reader(NULL);
413 if (!reader->PopVariant(&variant_reader))
414 return false;
415
keybuk@google.comf056b962012-03-22 08:43:45 +0900416 value_.clear();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900417 return variant_reader.PopArrayOfStrings(&value_);
418}
419
420template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900421void Property<std::vector<std::string> >::AppendSetValueToWriter(
422 MessageWriter* writer) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900423 MessageWriter variant_writer(NULL);
424 writer->OpenVariant("as", &variant_writer);
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900425 variant_writer.AppendArrayOfStrings(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900426 writer->CloseContainer(&variant_writer);
427}
428
429//
430// Property<std::vector<ObjectPath> > specialization.
431//
432
433template <>
434bool Property<std::vector<ObjectPath> >::PopValueFromReader(
435 MessageReader* reader) {
436 MessageReader variant_reader(NULL);
437 if (!reader->PopVariant(&variant_reader))
438 return false;
439
keybuk@google.comf056b962012-03-22 08:43:45 +0900440 value_.clear();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900441 return variant_reader.PopArrayOfObjectPaths(&value_);
442}
443
444template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900445void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
446 MessageWriter* writer) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900447 MessageWriter variant_writer(NULL);
448 writer->OpenVariant("ao", &variant_writer);
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900449 variant_writer.AppendArrayOfObjectPaths(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900450 writer->CloseContainer(&variant_writer);
451}
452
armansito@chromium.org11e12742014-03-15 16:40:49 +0900453//
454// Property<std::vector<uint8> > specialization.
455//
456
457template <>
458bool Property<std::vector<uint8> >::PopValueFromReader(MessageReader* reader) {
459 MessageReader variant_reader(NULL);
460 if (!reader->PopVariant(&variant_reader))
461 return false;
462
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;
470}
471
472template <>
473void 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);
479}
480
tzik@chromium.org1dc29432014-07-25 13:04:27 +0900481template class Property<uint8>;
482template class Property<bool>;
483template class Property<int16>;
484template class Property<uint16>;
485template class Property<int32>;
486template class Property<uint32>;
487template class Property<int64>;
488template class Property<uint64>;
489template class Property<double>;
490template class Property<std::string>;
491template class Property<ObjectPath>;
492template class Property<std::vector<std::string> >;
493template class Property<std::vector<ObjectPath> >;
494template class Property<std::vector<uint8> >;
495
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900496} // namespace dbus