Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / dbus / property.cc
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.
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
15 namespace dbus {
16
17 //
18 // PropertyBase implementation.
19 //
20
21 void 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
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) {}
40
41 PropertySet::~PropertySet() {
42 }
43
44 void PropertySet::RegisterProperty(const std::string& name,
45                                    PropertyBase* property) {
46   property->Init(this, name);
47   properties_map_[name] = property;
48 }
49
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()));
59 }
60
61
62 void PropertySet::ChangedReceived(Signal* signal) {
63   DCHECK(signal);
64   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
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.";
92 }
93
94
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());
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
110 void 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
125 void 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
137 void PropertySet::OnGetAll(Response* response) {
138   if (!response) {
139     LOG(WARNING) << "GetAll request failed for: " << interface_;
140     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
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);
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
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);
172 }
173
174 bool 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);
182     if (array_reader.PopDictEntry(&dict_entry_reader))
183       UpdatePropertyFromReader(&dict_entry_reader);
184   }
185
186   return true;
187 }
188
189 bool 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
210 void 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
219 template <>
220 Property<uint8>::Property() : value_(0) {
221 }
222
223 template <>
224 bool Property<uint8>::PopValueFromReader(MessageReader* reader) {
225   return reader->PopVariantOfByte(&value_);
226 }
227
228 template <>
229 void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer) {
230   writer->AppendVariantOfByte(set_value_);
231 }
232
233 //
234 // Property<bool> specialization.
235 //
236
237 template <>
238 Property<bool>::Property() : value_(false) {
239 }
240
241 template <>
242 bool Property<bool>::PopValueFromReader(MessageReader* reader) {
243   return reader->PopVariantOfBool(&value_);
244 }
245
246 template <>
247 void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
248   writer->AppendVariantOfBool(set_value_);
249 }
250
251 //
252 // Property<int16> specialization.
253 //
254
255 template <>
256 Property<int16>::Property() : value_(0) {
257 }
258
259 template <>
260 bool Property<int16>::PopValueFromReader(MessageReader* reader) {
261   return reader->PopVariantOfInt16(&value_);
262 }
263
264 template <>
265 void Property<int16>::AppendSetValueToWriter(MessageWriter* writer) {
266   writer->AppendVariantOfInt16(set_value_);
267 }
268
269 //
270 // Property<uint16> specialization.
271 //
272
273 template <>
274 Property<uint16>::Property() : value_(0) {
275 }
276
277 template <>
278 bool Property<uint16>::PopValueFromReader(MessageReader* reader) {
279   return reader->PopVariantOfUint16(&value_);
280 }
281
282 template <>
283 void Property<uint16>::AppendSetValueToWriter(MessageWriter* writer) {
284   writer->AppendVariantOfUint16(set_value_);
285 }
286
287 //
288 // Property<int32> specialization.
289 //
290
291 template <>
292 Property<int32>::Property() : value_(0) {
293 }
294
295 template <>
296 bool Property<int32>::PopValueFromReader(MessageReader* reader) {
297   return reader->PopVariantOfInt32(&value_);
298 }
299
300 template <>
301 void Property<int32>::AppendSetValueToWriter(MessageWriter* writer) {
302   writer->AppendVariantOfInt32(set_value_);
303 }
304
305 //
306 // Property<uint32> specialization.
307 //
308
309 template <>
310 Property<uint32>::Property() : value_(0) {
311 }
312
313 template <>
314 bool Property<uint32>::PopValueFromReader(MessageReader* reader) {
315   return reader->PopVariantOfUint32(&value_);
316 }
317
318 template <>
319 void Property<uint32>::AppendSetValueToWriter(MessageWriter* writer) {
320   writer->AppendVariantOfUint32(set_value_);
321 }
322
323 //
324 // Property<int64> specialization.
325 //
326
327 template <>
328 Property<int64>::Property() : value_(0), set_value_(0) {
329 }
330
331 template <>
332 bool Property<int64>::PopValueFromReader(MessageReader* reader) {
333   return reader->PopVariantOfInt64(&value_);
334 }
335
336 template <>
337 void Property<int64>::AppendSetValueToWriter(MessageWriter* writer) {
338   writer->AppendVariantOfInt64(set_value_);
339 }
340
341 //
342 // Property<uint64> specialization.
343 //
344
345 template <>
346 Property<uint64>::Property() : value_(0) {
347 }
348
349 template <>
350 bool Property<uint64>::PopValueFromReader(MessageReader* reader) {
351   return reader->PopVariantOfUint64(&value_);
352 }
353
354 template <>
355 void Property<uint64>::AppendSetValueToWriter(MessageWriter* writer) {
356   writer->AppendVariantOfUint64(set_value_);
357 }
358
359 //
360 // Property<double> specialization.
361 //
362
363 template <>
364 Property<double>::Property() : value_(0.0) {
365 }
366
367 template <>
368 bool Property<double>::PopValueFromReader(MessageReader* reader) {
369   return reader->PopVariantOfDouble(&value_);
370 }
371
372 template <>
373 void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
374   writer->AppendVariantOfDouble(set_value_);
375 }
376
377 //
378 // Property<std::string> specialization.
379 //
380
381 template <>
382 bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
383   return reader->PopVariantOfString(&value_);
384 }
385
386 template <>
387 void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
388   writer->AppendVariantOfString(set_value_);
389 }
390
391 //
392 // Property<ObjectPath> specialization.
393 //
394
395 template <>
396 bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
397   return reader->PopVariantOfObjectPath(&value_);
398 }
399
400 template <>
401 void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
402   writer->AppendVariantOfObjectPath(set_value_);
403 }
404
405 //
406 // Property<std::vector<std::string> > specialization.
407 //
408
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;
415
416   value_.clear();
417   return variant_reader.PopArrayOfStrings(&value_);
418 }
419
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);
427 }
428
429 //
430 // Property<std::vector<ObjectPath> > specialization.
431 //
432
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;
439
440   value_.clear();
441   return variant_reader.PopArrayOfObjectPaths(&value_);
442 }
443
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);
451 }
452
453 //
454 // Property<std::vector<uint8> > specialization.
455 //
456
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;
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
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);
479 }
480
481 template class Property<uint8>;
482 template class Property<bool>;
483 template class Property<int16>;
484 template class Property<uint16>;
485 template class Property<int32>;
486 template class Property<uint32>;
487 template class Property<int64>;
488 template class Property<uint64>;
489 template class Property<double>;
490 template class Property<std::string>;
491 template class Property<ObjectPath>;
492 template class Property<std::vector<std::string> >;
493 template class Property<std::vector<ObjectPath> >;
494 template class Property<std::vector<uint8> >;
495
496 }  // namespace dbus