blob: a20e0ad466fc0be6b9cbca788229684984a8ae69 [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#ifndef DBUS_PROPERTY_H_
6#define DBUS_PROPERTY_H_
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +09007
8#include <map>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/bind.h"
13#include "base/callback.h"
tfarina@chromium.org7928ea22012-11-05 10:56:14 +090014#include "dbus/dbus_export.h"
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090015#include "dbus/message.h"
16#include "dbus/object_proxy.h"
17
18// D-Bus objects frequently provide sets of properties accessed via a
19// standard interface of method calls and signals to obtain the current value,
20// set a new value and be notified of changes to the value. Unfortunately this
21// interface makes heavy use of variants and dictionaries of variants. The
22// classes defined here make dealing with properties in a type-safe manner
23// possible.
24//
25// Client implementation classes should define a Properties structure, deriving
26// from the PropertySet class defined here. This structure should contain a
27// member for each property defined as an instance of the Property<> class,
28// specifying the type to the template. Finally the structure should chain up
29// to the PropertySet constructor, and then call RegisterProperty() for each
30// property defined to associate them with their string name.
31//
32// Example:
33// class ExampleClient {
34// public:
35// struct Properties : public dbus::PropertySet {
36// dbus::Property<std::string> name;
37// dbus::Property<uint16> version;
38// dbus::Property<dbus::ObjectPath> parent;
39// dbus::Property<std::vector<std::string> > children;
40//
41// Properties(dbus::ObjectProxy* object_proxy,
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +090042// const PropertyChangedCallback callback)
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090043// : dbus::PropertySet(object_proxy, "com.example.DBus", callback) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090044// RegisterProperty("Name", &name);
45// RegisterProperty("Version", &version);
46// RegisterProperty("Parent", &parent);
47// RegisterProperty("Children", &children);
48// }
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090049// virtual ~Properties() {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090050// };
51//
52// The Properties structure requires a pointer to the object proxy of the
53// actual object to track, and after construction should have signals
54// connected to that object and initial values set by calling ConnectSignals()
55// and GetAll(). The structure should not outlive the object proxy, so it
56// is recommended that the lifecycle of both be managed together.
57//
58// Example (continued):
59//
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090060// typedef std::map<std::pair<dbus::ObjectProxy*, Properties*> > Object;
61// typedef std::map<dbus::ObjectPath, Object> ObjectMap;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090062// ObjectMap object_map_;
63//
64// dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path) {
65// return GetObject(object_path).first;
66// }
67//
68// Properties* GetProperties(const dbus::ObjectPath& object_path) {
69// return GetObject(object_path).second;
70// }
71//
72// Object GetObject(const dbus::ObjectPath& object_path) {
73// ObjectMap::iterator it = object_map_.find(object_path);
74// if (it != object_map_.end())
75// return it->second;
76//
77// dbus::ObjectProxy* object_proxy = bus->GetObjectProxy(...);
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090078// // connect signals, etc.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090079//
80// Properties* properties = new Properties(
81// object_proxy,
82// base::Bind(&PropertyChanged,
83// weak_ptr_factory_.GetWeakPtr(),
84// object_path));
85// properties->ConnectSignals();
86// properties->GetAll();
87//
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090088// Object object = std::make_pair(object_proxy, properties);
89// object_map_[object_path] = object;
90// return object;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090091// }
92// };
93//
94// This now allows code using the client implementation to access properties
95// in a type-safe manner, and assuming the PropertyChanged callback is
96// propogated up to observers, be notified of changes. A typical access of
97// the current value of the name property would be:
98//
99// ExampleClient::Properties* p = example_client->GetProperties(object_path);
100// std::string name = p->name.value();
101//
102// Normally these values are updated from signals emitted by the remote object,
103// in case an explicit round-trip is needed to obtain the current value, the
104// Get() method can be used and indicates whether or not the value update was
105// successful. The updated value can be obtained in the callback using the
106// value() method.
107//
108// p->children.Get(base::Bind(&OnGetChildren));
109//
110// A new value can be set using the Set() method, the callback indicates
111// success only; it is up to the remote object when (and indeed if) it updates
112// the property value, and whether it emits a signal or a Get() call is
113// required to obtain it.
114//
115// p->version.Set(20, base::Bind(&OnSetVersion))
116
117namespace dbus {
118
119// D-Bus Properties interface constants, declared here rather than
120// in property.cc because template methods use them.
121const char kPropertiesInterface[] = "org.freedesktop.DBus.Properties";
122const char kPropertiesGetAll[] = "GetAll";
123const char kPropertiesGet[] = "Get";
124const char kPropertiesSet[] = "Set";
125const char kPropertiesChanged[] = "PropertiesChanged";
126
127class PropertySet;
128
129// PropertyBase is an abstract base-class consisting of the parts of
130// the Property<> template that are not type-specific, such as the
131// associated PropertySet, property name, and the type-unsafe parts
132// used by PropertySet.
133class PropertyBase {
134 public:
135 PropertyBase() : property_set_(NULL) {}
136
137 // Initializes the |property_set| and property |name| so that method
138 // calls may be made from this class. This method is called by
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900139 // PropertySet::RegisterProperty() passing |this| for |property_set| so
140 // there should be no need to call it directly. If you do beware that
141 // no ownership or reference to |property_set| is taken so that object
142 // must outlive this one.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900143 void Init(PropertySet* property_set, const std::string& name);
144
145 // Retrieves the name of this property, this may be useful in observers
146 // to avoid specifying the name in more than once place, e.g.
147 //
148 // void Client::PropertyChanged(const dbus::ObjectPath& object_path,
149 // const std::string &property_name) {
150 // Properties& properties = GetProperties(object_path);
151 // if (property_name == properties.version.name()) {
152 // // Handle version property changing
153 // }
154 // }
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900155 const std::string& name() const { return name_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900156
157 // Method used by PropertySet to retrieve the value from a MessageReader,
158 // no knowledge of the contained type is required, this method returns
159 // true if its expected type was found, false if not.
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900160 // Implementation provided by specialization.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900161 virtual bool PopValueFromReader(MessageReader*) = 0;
162
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900163 // Method used by PropertySet to append the set value to a MessageWriter,
164 // no knowledge of the contained type is required.
165 // Implementation provided by specialization.
166 virtual void AppendSetValueToWriter(MessageWriter* writer) = 0;
167
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900168 // Method used by test and stub implementations of dbus::PropertySet::Set
169 // to replace the property value with the set value without using a
170 // dbus::MessageReader.
171 virtual void ReplaceValueWithSetValue() = 0;
172
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900173 protected:
174 // Retrieves the associated property set.
175 PropertySet* property_set() { return property_set_; }
176
177 private:
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900178 // Pointer to the PropertySet instance that this instance is a member of,
179 // no ownership is taken and |property_set_| must outlive this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900180 PropertySet* property_set_;
181
182 // Name of the property.
183 std::string name_;
184
185 DISALLOW_COPY_AND_ASSIGN(PropertyBase);
186};
187
188// PropertySet groups a collection of properties for a remote object
189// together into a single structure, fixing their types and name such
190// that calls made through it are type-safe.
191//
192// Clients always sub-class this to add the properties, and should always
193// provide a constructor that chains up to this and then calls
194// RegisterProperty() for each property defined.
195//
196// After creation, client code should call ConnectSignals() and most likely
197// GetAll() to seed initial values and update as changes occur.
tfarina@chromium.org7928ea22012-11-05 10:56:14 +0900198class CHROME_DBUS_EXPORT PropertySet {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900199 public:
200 // Callback for changes to cached values of properties, either notified
201 // via signal, or as a result of calls to Get() and GetAll(). The |name|
202 // argument specifies the name of the property changed.
203 typedef base::Callback<void(const std::string& name)> PropertyChangedCallback;
204
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900205 // Constructs a property set, where |object_proxy| specifies the proxy for
206 // the/ remote object that these properties are for, care should be taken to
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900207 // ensure that this object does not outlive the lifetime of the proxy;
208 // |interface| specifies the D-Bus interface of these properties, and
209 // |property_changed_callback| specifies the callback for when properties
210 // are changed, this may be a NULL callback.
211 PropertySet(ObjectProxy* object_proxy, const std::string& interface,
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900212 const PropertyChangedCallback& property_changed_callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900213
214 // Destructor; we don't hold on to any references or memory that needs
215 // explicit clean-up, but clang thinks we might.
keybuk@chromium.org82e082a2012-02-17 10:01:18 +0900216 virtual ~PropertySet();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900217
218 // Registers a property, generally called from the subclass constructor;
219 // pass the |name| of the property as used in method calls and signals,
220 // and the pointer to the |property| member of the structure. This will
221 // call the PropertyBase::Init method.
222 void RegisterProperty(const std::string& name, PropertyBase* property);
223
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900224 // Connects property change notification signals to the object, generally
225 // called immediately after the object is created and before calls to other
226 // methods. Sub-classes may override to use different D-Bus signals.
227 virtual void ConnectSignals();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900228
229 // Methods connected by ConnectSignals() and called by dbus:: when
230 // a property is changed. Sub-classes may override if the property
231 // changed signal provides different arguments.
232 virtual void ChangedReceived(Signal*);
233 virtual void ChangedConnected(const std::string& interface_name,
234 const std::string& signal_name,
235 bool success);
236
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900237 // Callback for Get() method, |success| indicates whether or not the
238 // value could be retrived, if true the new value can be obtained by
239 // calling value() on the property.
240 typedef base::Callback<void(bool success)> GetCallback;
241
242 // Requests an updated value from the remote object for |property|
243 // incurring a round-trip. |callback| will be called when the new
244 // value is available. This may not be implemented by some interfaces,
245 // and may be overriden by sub-classes if interfaces use different
246 // method calls.
247 virtual void Get(PropertyBase* property, GetCallback callback);
248 virtual void OnGet(PropertyBase* property, GetCallback callback,
249 Response* response);
250
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +0900251 // Queries the remote object for values of all properties and updates
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900252 // initial values. Sub-classes may override to use a different D-Bus
253 // method, or if the remote object does not support retrieving all
254 // properties, either ignore or obtain each property value individually.
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900255 virtual void GetAll();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900256 virtual void OnGetAll(Response* response);
257
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900258 // Callback for Set() method, |success| indicates whether or not the
259 // new property value was accepted by the remote object.
260 typedef base::Callback<void(bool success)> SetCallback;
261
262 // Requests that the remote object for |property| change the property to
263 // its new value. |callback| will be called to indicate the success or
264 // failure of the request, however the new value may not be available
265 // depending on the remote object. This method may be overridden by
266 // sub-classes if interfaces use different method calls.
267 virtual void Set(PropertyBase* property, SetCallback callback);
268 virtual void OnSet(PropertyBase* property, SetCallback callback,
269 Response* response);
270
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900271 // Update properties by reading an array of dictionary entries, each
272 // containing a string with the name and a variant with the value, from
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900273 // |message_reader|. Returns false if message is in incorrect format.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900274 bool UpdatePropertiesFromReader(MessageReader* reader);
275
276 // Updates a single property by reading a string with the name and a
277 // variant with the value from |message_reader|. Returns false if message
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900278 // is in incorrect format, or property type doesn't match.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900279 bool UpdatePropertyFromReader(MessageReader* reader);
280
281 // Calls the property changed callback passed to the constructor, used
282 // by sub-classes that do not call UpdatePropertiesFromReader() or
283 // UpdatePropertyFromReader(). Takes the |name| of the changed property.
284 void NotifyPropertyChanged(const std::string& name);
285
286 // Retrieves the object proxy this property set was initialized with,
287 // provided for sub-classes overriding methods that make D-Bus calls
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900288 // and for Property<>. Not permitted with const references to this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900289 ObjectProxy* object_proxy() { return object_proxy_; }
290
291 // Retrieves the interface of this property set.
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900292 const std::string& interface() const { return interface_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900293
294 protected:
295 // Get a weak pointer to this property set, provided so that sub-classes
296 // overriding methods that make D-Bus calls may use the existing (or
297 // override) callbacks without providing their own weak pointer factory.
298 base::WeakPtr<PropertySet> GetWeakPtr() {
299 return weak_ptr_factory_.GetWeakPtr();
300 }
301
302 private:
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900303 // Pointer to object proxy for making method calls, no ownership is taken
304 // so this must outlive this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900305 ObjectProxy* object_proxy_;
306
307 // Interface of property, e.g. "org.chromium.ExampleService", this is
308 // distinct from the interface of the method call itself which is the
309 // general D-Bus Properties interface "org.freedesktop.DBus.Properties".
310 std::string interface_;
311
312 // Callback for property changes.
313 PropertyChangedCallback property_changed_callback_;
314
315 // Map of properties (as PropertyBase*) defined in the structure to
316 // names as used in D-Bus method calls and signals. The base pointer
317 // restricts property access via this map to type-unsafe and non-specific
318 // actions only.
319 typedef std::map<const std::string, PropertyBase*> PropertiesMap;
320 PropertiesMap properties_map_;
321
322 // Weak pointer factory as D-Bus callbacks may last longer than these
323 // objects.
324 base::WeakPtrFactory<PropertySet> weak_ptr_factory_;
325
326 DISALLOW_COPY_AND_ASSIGN(PropertySet);
327};
328
329// Property template, this defines the type-specific and type-safe methods
330// of properties that can be accessed as members of a PropertySet structure.
331//
332// Properties provide a cached value that has an initial sensible default
333// until the reply to PropertySet::GetAll() is retrieved and is updated by
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900334// all calls to that method, PropertySet::Get() and property changed signals
335// also handled by PropertySet. It can be obtained by calling value() on the
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900336// property.
337//
338// It is recommended that this cached value be used where necessary, with
339// code using PropertySet::PropertyChangedCallback to be notified of changes,
340// rather than incurring a round-trip to the remote object for each property
341// access.
342//
343// Where a round-trip is necessary, the Get() method is provided. And to
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900344// update the remote object value, the Set() method is also provided; these
345// both simply call methods on PropertySet.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900346//
347// Handling of particular D-Bus types is performed via specialization,
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900348// typically the PopValueFromReader() and AppendSetValueToWriter() methods
349// will need to be provided, and in rare cases a constructor to provide a
350// default value. Specializations for basic D-Bus types, strings, object
351// paths and arrays are provided for you.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900352template <class T>
tzik@chromium.org57fd8b12014-06-27 17:10:43 +0900353class CHROME_DBUS_EXPORT Property : public PropertyBase {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900354 public:
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900355 Property() {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900356
357 // Retrieves the cached value.
keybuk@chromium.org5b48ae42012-02-17 16:46:34 +0900358 const T& value() const { return value_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900359
360 // Requests an updated value from the remote object incurring a
361 // round-trip. |callback| will be called when the new value is available.
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900362 // This may not be implemented by some interfaces.
363 virtual void Get(dbus::PropertySet::GetCallback callback) {
364 property_set()->Get(this, callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900365 }
366
367 // Requests that the remote object change the property value to |value|,
368 // |callback| will be called to indicate the success or failure of the
369 // request, however the new value may not be available depending on the
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900370 // remote object.
371 virtual void Set(const T& value, dbus::PropertySet::SetCallback callback) {
372 set_value_ = value;
373 property_set()->Set(this, callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900374 }
375
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900376 // Method used by PropertySet to retrieve the value from a MessageReader,
377 // no knowledge of the contained type is required, this method returns
378 // true if its expected type was found, false if not.
379 virtual bool PopValueFromReader(MessageReader*);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900380
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900381 // Method used by PropertySet to append the set value to a MessageWriter,
382 // no knowledge of the contained type is required.
keybuk@google.comf056b962012-03-22 08:43:45 +0900383 // Implementation provided by specialization.
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900384 virtual void AppendSetValueToWriter(MessageWriter* writer);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900385
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900386 // Method used by test and stub implementations of dbus::PropertySet::Set
387 // to replace the property value with the set value without using a
388 // dbus::MessageReader.
keybuk@chromium.orgc1944c62013-04-24 10:41:54 +0900389 virtual void ReplaceValueWithSetValue() {
390 value_ = set_value_;
391 property_set()->NotifyPropertyChanged(name());
392 }
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900393
394 // Method used by test and stub implementations to directly set the
395 // value of a property.
keybuk@chromium.orgc1944c62013-04-24 10:41:54 +0900396 void ReplaceValue(const T& value) {
397 value_ = value;
398 property_set()->NotifyPropertyChanged(name());
399 }
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900400
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900401 private:
402 // Current cached value of the property.
403 T value_;
404
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900405 // Replacement value of the property.
406 T set_value_;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900407};
408
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900409template <> Property<uint8>::Property();
410template <> bool Property<uint8>::PopValueFromReader(MessageReader* reader);
411template <> void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900412extern template class Property<uint8>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900413
414template <> Property<bool>::Property();
415template <> bool Property<bool>::PopValueFromReader(MessageReader* reader);
416template <> void Property<bool>::AppendSetValueToWriter(MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900417extern template class Property<bool>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900418
419template <> Property<int16>::Property();
420template <> bool Property<int16>::PopValueFromReader(MessageReader* reader);
421template <> void Property<int16>::AppendSetValueToWriter(MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900422extern template class Property<int16>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900423
424template <> Property<uint16>::Property();
425template <> bool Property<uint16>::PopValueFromReader(MessageReader* reader);
426template <> void Property<uint16>::AppendSetValueToWriter(
427 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900428extern template class Property<uint16>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900429
430template <> Property<int32>::Property();
431template <> bool Property<int32>::PopValueFromReader(MessageReader* reader);
432template <> void Property<int32>::AppendSetValueToWriter(MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900433extern template class Property<int32>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900434
435template <> Property<uint32>::Property();
436template <> bool Property<uint32>::PopValueFromReader(MessageReader* reader);
437template <> void Property<uint32>::AppendSetValueToWriter(
438 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900439extern template class Property<uint32>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900440
441template <> Property<int64>::Property();
442template <> bool Property<int64>::PopValueFromReader(MessageReader* reader);
443template <> void Property<int64>::AppendSetValueToWriter(MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900444extern template class Property<int64>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900445
446template <> Property<uint64>::Property();
447template <> bool Property<uint64>::PopValueFromReader(MessageReader* reader);
448template <> void Property<uint64>::AppendSetValueToWriter(
449 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900450extern template class Property<uint64>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900451
452template <> Property<double>::Property();
453template <> bool Property<double>::PopValueFromReader(MessageReader* reader);
454template <> void Property<double>::AppendSetValueToWriter(
455 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900456extern template class Property<double>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900457
458template <> bool Property<std::string>::PopValueFromReader(
459 MessageReader* reader);
460template <> void Property<std::string>::AppendSetValueToWriter(
461 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900462extern template class Property<std::string>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900463
464template <> bool Property<ObjectPath>::PopValueFromReader(
465 MessageReader* reader);
466template <> void Property<ObjectPath>::AppendSetValueToWriter(
467 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900468extern template class Property<ObjectPath>;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900469
470template <> bool Property<std::vector<std::string> >::PopValueFromReader(
471 MessageReader* reader);
472template <> void Property<std::vector<std::string> >::AppendSetValueToWriter(
473 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900474extern template class Property<std::vector<std::string> >;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900475
476template <> bool Property<std::vector<ObjectPath> >::PopValueFromReader(
477 MessageReader* reader);
478template <> void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
479 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900480extern template class Property<std::vector<ObjectPath> >;
keybuk@chromium.org80dcd9c2012-09-22 07:55:17 +0900481
armansito@chromium.org11e12742014-03-15 16:40:49 +0900482template <> bool Property<std::vector<uint8> >::PopValueFromReader(
483 MessageReader* reader);
484template <> void Property<std::vector<uint8> >::AppendSetValueToWriter(
485 MessageWriter* writer);
mostynb@opera.com4d98e822014-07-31 03:44:31 +0900486extern template class Property<std::vector<uint8> >;
armansito@chromium.org11e12742014-03-15 16:40:49 +0900487
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900488} // namespace dbus
489
490#endif // DBUS_PROPERTY_H_