- add sources.
[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.";
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, SetCallback callback,
167                         Response* response) {
168   LOG_IF(WARNING, !response) << property->name() << ": Set: failed.";
169   if (!callback.is_null())
170     callback.Run(response);
171 }
172
173 bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
174   DCHECK(reader);
175   MessageReader array_reader(NULL);
176   if (!reader->PopArray(&array_reader))
177     return false;
178
179   while (array_reader.HasMoreData()) {
180     MessageReader dict_entry_reader(NULL);
181     if (array_reader.PopDictEntry(&dict_entry_reader))
182       UpdatePropertyFromReader(&dict_entry_reader);
183   }
184
185   return true;
186 }
187
188 bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
189   DCHECK(reader);
190
191   std::string name;
192   if (!reader->PopString(&name))
193     return false;
194
195   PropertiesMap::iterator it = properties_map_.find(name);
196   if (it == properties_map_.end())
197     return false;
198
199   PropertyBase* property = it->second;
200   if (property->PopValueFromReader(reader)) {
201     NotifyPropertyChanged(name);
202     return true;
203   } else {
204     return false;
205   }
206 }
207
208
209 void PropertySet::NotifyPropertyChanged(const std::string& name) {
210   if (!property_changed_callback_.is_null())
211     property_changed_callback_.Run(name);
212 }
213
214 //
215 // Property<Byte> specialization.
216 //
217
218 template <>
219 Property<uint8>::Property() : value_(0) {
220 }
221
222 template <>
223 bool Property<uint8>::PopValueFromReader(MessageReader* reader) {
224   return reader->PopVariantOfByte(&value_);
225 }
226
227 template <>
228 void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer) {
229   writer->AppendVariantOfByte(set_value_);
230 }
231
232 //
233 // Property<bool> specialization.
234 //
235
236 template <>
237 Property<bool>::Property() : value_(false) {
238 }
239
240 template <>
241 bool Property<bool>::PopValueFromReader(MessageReader* reader) {
242   return reader->PopVariantOfBool(&value_);
243 }
244
245 template <>
246 void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
247   writer->AppendVariantOfBool(set_value_);
248 }
249
250 //
251 // Property<int16> specialization.
252 //
253
254 template <>
255 Property<int16>::Property() : value_(0) {
256 }
257
258 template <>
259 bool Property<int16>::PopValueFromReader(MessageReader* reader) {
260   return reader->PopVariantOfInt16(&value_);
261 }
262
263 template <>
264 void Property<int16>::AppendSetValueToWriter(MessageWriter* writer) {
265   writer->AppendVariantOfInt16(set_value_);
266 }
267
268 //
269 // Property<uint16> specialization.
270 //
271
272 template <>
273 Property<uint16>::Property() : value_(0) {
274 }
275
276 template <>
277 bool Property<uint16>::PopValueFromReader(MessageReader* reader) {
278   return reader->PopVariantOfUint16(&value_);
279 }
280
281 template <>
282 void Property<uint16>::AppendSetValueToWriter(MessageWriter* writer) {
283   writer->AppendVariantOfUint16(set_value_);
284 }
285
286 //
287 // Property<int32> specialization.
288 //
289
290 template <>
291 Property<int32>::Property() : value_(0) {
292 }
293
294 template <>
295 bool Property<int32>::PopValueFromReader(MessageReader* reader) {
296   return reader->PopVariantOfInt32(&value_);
297 }
298
299 template <>
300 void Property<int32>::AppendSetValueToWriter(MessageWriter* writer) {
301   writer->AppendVariantOfInt32(set_value_);
302 }
303
304 //
305 // Property<uint32> specialization.
306 //
307
308 template <>
309 Property<uint32>::Property() : value_(0) {
310 }
311
312 template <>
313 bool Property<uint32>::PopValueFromReader(MessageReader* reader) {
314   return reader->PopVariantOfUint32(&value_);
315 }
316
317 template <>
318 void Property<uint32>::AppendSetValueToWriter(MessageWriter* writer) {
319   writer->AppendVariantOfUint32(set_value_);
320 }
321
322 //
323 // Property<int64> specialization.
324 //
325
326 template <>
327 Property<int64>::Property() : value_(0), set_value_(0) {
328 }
329
330 template <>
331 bool Property<int64>::PopValueFromReader(MessageReader* reader) {
332   return reader->PopVariantOfInt64(&value_);
333 }
334
335 template <>
336 void Property<int64>::AppendSetValueToWriter(MessageWriter* writer) {
337   writer->AppendVariantOfInt64(set_value_);
338 }
339
340 //
341 // Property<uint64> specialization.
342 //
343
344 template <>
345 Property<uint64>::Property() : value_(0) {
346 }
347
348 template <>
349 bool Property<uint64>::PopValueFromReader(MessageReader* reader) {
350   return reader->PopVariantOfUint64(&value_);
351 }
352
353 template <>
354 void Property<uint64>::AppendSetValueToWriter(MessageWriter* writer) {
355   writer->AppendVariantOfUint64(set_value_);
356 }
357
358 //
359 // Property<double> specialization.
360 //
361
362 template <>
363 Property<double>::Property() : value_(0.0) {
364 }
365
366 template <>
367 bool Property<double>::PopValueFromReader(MessageReader* reader) {
368   return reader->PopVariantOfDouble(&value_);
369 }
370
371 template <>
372 void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
373   writer->AppendVariantOfDouble(set_value_);
374 }
375
376 //
377 // Property<std::string> specialization.
378 //
379
380 template <>
381 bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
382   return reader->PopVariantOfString(&value_);
383 }
384
385 template <>
386 void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
387   writer->AppendVariantOfString(set_value_);
388 }
389
390 //
391 // Property<ObjectPath> specialization.
392 //
393
394 template <>
395 bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
396   return reader->PopVariantOfObjectPath(&value_);
397 }
398
399 template <>
400 void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
401   writer->AppendVariantOfObjectPath(set_value_);
402 }
403
404 //
405 // Property<std::vector<std::string> > specialization.
406 //
407
408 template <>
409 bool Property<std::vector<std::string> >::PopValueFromReader(
410     MessageReader* reader) {
411   MessageReader variant_reader(NULL);
412   if (!reader->PopVariant(&variant_reader))
413     return false;
414
415   value_.clear();
416   return variant_reader.PopArrayOfStrings(&value_);
417 }
418
419 template <>
420 void Property<std::vector<std::string> >::AppendSetValueToWriter(
421     MessageWriter* writer) {
422   MessageWriter variant_writer(NULL);
423   writer->OpenVariant("as", &variant_writer);
424   variant_writer.AppendArrayOfStrings(set_value_);
425   writer->CloseContainer(&variant_writer);
426 }
427
428 //
429 // Property<std::vector<ObjectPath> > specialization.
430 //
431
432 template <>
433 bool Property<std::vector<ObjectPath> >::PopValueFromReader(
434     MessageReader* reader) {
435   MessageReader variant_reader(NULL);
436   if (!reader->PopVariant(&variant_reader))
437     return false;
438
439   value_.clear();
440   return variant_reader.PopArrayOfObjectPaths(&value_);
441 }
442
443 template <>
444 void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
445     MessageWriter* writer) {
446   MessageWriter variant_writer(NULL);
447   writer->OpenVariant("ao", &variant_writer);
448   variant_writer.AppendArrayOfObjectPaths(set_value_);
449   writer->CloseContainer(&variant_writer);
450 }
451
452 }  // namespace dbus