blob: e379f8a1618720241bdc75efa1f6259f3002c881 [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>
dtapuska95f71722015-02-10 01:02:55 +090010#include <utility>
11#include <vector>
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090012
13#include "base/basictypes.h"
14#include "base/bind.h"
15#include "base/callback.h"
tfarina@chromium.org7928ea22012-11-05 10:56:14 +090016#include "dbus/dbus_export.h"
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090017#include "dbus/message.h"
18#include "dbus/object_proxy.h"
19
20// D-Bus objects frequently provide sets of properties accessed via a
21// standard interface of method calls and signals to obtain the current value,
22// set a new value and be notified of changes to the value. Unfortunately this
23// interface makes heavy use of variants and dictionaries of variants. The
24// classes defined here make dealing with properties in a type-safe manner
25// possible.
26//
27// Client implementation classes should define a Properties structure, deriving
28// from the PropertySet class defined here. This structure should contain a
29// member for each property defined as an instance of the Property<> class,
30// specifying the type to the template. Finally the structure should chain up
31// to the PropertySet constructor, and then call RegisterProperty() for each
32// property defined to associate them with their string name.
33//
34// Example:
35// class ExampleClient {
36// public:
37// struct Properties : public dbus::PropertySet {
38// dbus::Property<std::string> name;
39// dbus::Property<uint16> version;
40// dbus::Property<dbus::ObjectPath> parent;
41// dbus::Property<std::vector<std::string> > children;
42//
43// Properties(dbus::ObjectProxy* object_proxy,
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +090044// const PropertyChangedCallback callback)
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090045// : dbus::PropertySet(object_proxy, "com.example.DBus", callback) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090046// RegisterProperty("Name", &name);
47// RegisterProperty("Version", &version);
48// RegisterProperty("Parent", &parent);
49// RegisterProperty("Children", &children);
50// }
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090051// virtual ~Properties() {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090052// };
53//
54// The Properties structure requires a pointer to the object proxy of the
55// actual object to track, and after construction should have signals
56// connected to that object and initial values set by calling ConnectSignals()
57// and GetAll(). The structure should not outlive the object proxy, so it
58// is recommended that the lifecycle of both be managed together.
59//
60// Example (continued):
61//
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090062// typedef std::map<std::pair<dbus::ObjectProxy*, Properties*> > Object;
63// typedef std::map<dbus::ObjectPath, Object> ObjectMap;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090064// ObjectMap object_map_;
65//
66// dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path) {
67// return GetObject(object_path).first;
68// }
69//
70// Properties* GetProperties(const dbus::ObjectPath& object_path) {
71// return GetObject(object_path).second;
72// }
73//
74// Object GetObject(const dbus::ObjectPath& object_path) {
75// ObjectMap::iterator it = object_map_.find(object_path);
76// if (it != object_map_.end())
77// return it->second;
78//
79// dbus::ObjectProxy* object_proxy = bus->GetObjectProxy(...);
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090080// // connect signals, etc.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090081//
82// Properties* properties = new Properties(
83// object_proxy,
84// base::Bind(&PropertyChanged,
85// weak_ptr_factory_.GetWeakPtr(),
86// object_path));
87// properties->ConnectSignals();
88// properties->GetAll();
89//
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090090// Object object = std::make_pair(object_proxy, properties);
91// object_map_[object_path] = object;
92// return object;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090093// }
94// };
95//
96// This now allows code using the client implementation to access properties
97// in a type-safe manner, and assuming the PropertyChanged callback is
98// propogated up to observers, be notified of changes. A typical access of
99// the current value of the name property would be:
100//
101// ExampleClient::Properties* p = example_client->GetProperties(object_path);
102// std::string name = p->name.value();
103//
104// Normally these values are updated from signals emitted by the remote object,
105// in case an explicit round-trip is needed to obtain the current value, the
106// Get() method can be used and indicates whether or not the value update was
107// successful. The updated value can be obtained in the callback using the
108// value() method.
109//
110// p->children.Get(base::Bind(&OnGetChildren));
111//
112// A new value can be set using the Set() method, the callback indicates
113// success only; it is up to the remote object when (and indeed if) it updates
114// the property value, and whether it emits a signal or a Get() call is
115// required to obtain it.
116//
117// p->version.Set(20, base::Bind(&OnSetVersion))
118
119namespace dbus {
120
121// D-Bus Properties interface constants, declared here rather than
122// in property.cc because template methods use them.
123const char kPropertiesInterface[] = "org.freedesktop.DBus.Properties";
124const char kPropertiesGetAll[] = "GetAll";
125const char kPropertiesGet[] = "Get";
126const char kPropertiesSet[] = "Set";
127const char kPropertiesChanged[] = "PropertiesChanged";
128
129class PropertySet;
130
131// PropertyBase is an abstract base-class consisting of the parts of
132// the Property<> template that are not type-specific, such as the
133// associated PropertySet, property name, and the type-unsafe parts
134// used by PropertySet.
derat3f868a42015-07-17 00:06:44 +0900135class CHROME_DBUS_EXPORT PropertyBase {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900136 public:
derat3f868a42015-07-17 00:06:44 +0900137 PropertyBase();
138 virtual ~PropertyBase();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900139
140 // Initializes the |property_set| and property |name| so that method
141 // calls may be made from this class. This method is called by
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900142 // PropertySet::RegisterProperty() passing |this| for |property_set| so
143 // there should be no need to call it directly. If you do beware that
144 // no ownership or reference to |property_set| is taken so that object
145 // must outlive this one.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900146 void Init(PropertySet* property_set, const std::string& name);
147
148 // Retrieves the name of this property, this may be useful in observers
149 // to avoid specifying the name in more than once place, e.g.
150 //
151 // void Client::PropertyChanged(const dbus::ObjectPath& object_path,
152 // const std::string &property_name) {
153 // Properties& properties = GetProperties(object_path);
154 // if (property_name == properties.version.name()) {
155 // // Handle version property changing
156 // }
157 // }
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900158 const std::string& name() const { return name_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900159
jpawlowski77e73fc2015-05-11 20:07:04 +0900160 // Returns true if property is valid, false otherwise.
161 bool is_valid() const { return is_valid_; }
162
163 // Allows to mark Property as valid or invalid.
164 void set_valid(bool is_valid) { is_valid_ = is_valid; }
165
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900166 // Method used by PropertySet to retrieve the value from a MessageReader,
167 // no knowledge of the contained type is required, this method returns
168 // true if its expected type was found, false if not.
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900169 // Implementation provided by specialization.
dtapuska95f71722015-02-10 01:02:55 +0900170 virtual bool PopValueFromReader(MessageReader* reader) = 0;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900171
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900172 // Method used by PropertySet to append the set value to a MessageWriter,
173 // no knowledge of the contained type is required.
174 // Implementation provided by specialization.
175 virtual void AppendSetValueToWriter(MessageWriter* writer) = 0;
176
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900177 // Method used by test and stub implementations of dbus::PropertySet::Set
178 // to replace the property value with the set value without using a
179 // dbus::MessageReader.
180 virtual void ReplaceValueWithSetValue() = 0;
181
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900182 protected:
183 // Retrieves the associated property set.
184 PropertySet* property_set() { return property_set_; }
185
186 private:
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900187 // Pointer to the PropertySet instance that this instance is a member of,
188 // no ownership is taken and |property_set_| must outlive this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900189 PropertySet* property_set_;
190
jpawlowski77e73fc2015-05-11 20:07:04 +0900191 bool is_valid_;
192
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900193 // Name of the property.
194 std::string name_;
195
196 DISALLOW_COPY_AND_ASSIGN(PropertyBase);
197};
198
199// PropertySet groups a collection of properties for a remote object
200// together into a single structure, fixing their types and name such
201// that calls made through it are type-safe.
202//
203// Clients always sub-class this to add the properties, and should always
204// provide a constructor that chains up to this and then calls
205// RegisterProperty() for each property defined.
206//
207// After creation, client code should call ConnectSignals() and most likely
208// GetAll() to seed initial values and update as changes occur.
tfarina@chromium.org7928ea22012-11-05 10:56:14 +0900209class CHROME_DBUS_EXPORT PropertySet {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900210 public:
211 // Callback for changes to cached values of properties, either notified
212 // via signal, or as a result of calls to Get() and GetAll(). The |name|
213 // argument specifies the name of the property changed.
214 typedef base::Callback<void(const std::string& name)> PropertyChangedCallback;
215
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900216 // Constructs a property set, where |object_proxy| specifies the proxy for
217 // the/ remote object that these properties are for, care should be taken to
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900218 // ensure that this object does not outlive the lifetime of the proxy;
219 // |interface| specifies the D-Bus interface of these properties, and
220 // |property_changed_callback| specifies the callback for when properties
221 // are changed, this may be a NULL callback.
222 PropertySet(ObjectProxy* object_proxy, const std::string& interface,
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900223 const PropertyChangedCallback& property_changed_callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900224
225 // Destructor; we don't hold on to any references or memory that needs
226 // explicit clean-up, but clang thinks we might.
keybuk@chromium.org82e082a2012-02-17 10:01:18 +0900227 virtual ~PropertySet();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900228
229 // Registers a property, generally called from the subclass constructor;
230 // pass the |name| of the property as used in method calls and signals,
231 // and the pointer to the |property| member of the structure. This will
232 // call the PropertyBase::Init method.
233 void RegisterProperty(const std::string& name, PropertyBase* property);
234
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900235 // Connects property change notification signals to the object, generally
236 // called immediately after the object is created and before calls to other
237 // methods. Sub-classes may override to use different D-Bus signals.
238 virtual void ConnectSignals();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900239
240 // Methods connected by ConnectSignals() and called by dbus:: when
241 // a property is changed. Sub-classes may override if the property
242 // changed signal provides different arguments.
dtapuska95f71722015-02-10 01:02:55 +0900243 virtual void ChangedReceived(Signal* signal);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900244 virtual void ChangedConnected(const std::string& interface_name,
245 const std::string& signal_name,
246 bool success);
247
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900248 // Callback for Get() method, |success| indicates whether or not the
249 // value could be retrived, if true the new value can be obtained by
250 // calling value() on the property.
251 typedef base::Callback<void(bool success)> GetCallback;
252
253 // Requests an updated value from the remote object for |property|
254 // incurring a round-trip. |callback| will be called when the new
255 // value is available. This may not be implemented by some interfaces,
256 // and may be overriden by sub-classes if interfaces use different
257 // method calls.
258 virtual void Get(PropertyBase* property, GetCallback callback);
259 virtual void OnGet(PropertyBase* property, GetCallback callback,
260 Response* response);
261
nywang80f27162015-09-29 07:46:36 +0900262 // The synchronous version of Get().
263 // This should never be used on an interactive thread.
264 virtual bool GetAndBlock(PropertyBase* property);
265
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +0900266 // Queries the remote object for values of all properties and updates
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900267 // initial values. Sub-classes may override to use a different D-Bus
268 // method, or if the remote object does not support retrieving all
269 // properties, either ignore or obtain each property value individually.
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900270 virtual void GetAll();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900271 virtual void OnGetAll(Response* response);
272
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900273 // Callback for Set() method, |success| indicates whether or not the
274 // new property value was accepted by the remote object.
275 typedef base::Callback<void(bool success)> SetCallback;
276
277 // Requests that the remote object for |property| change the property to
278 // its new value. |callback| will be called to indicate the success or
279 // failure of the request, however the new value may not be available
280 // depending on the remote object. This method may be overridden by
281 // sub-classes if interfaces use different method calls.
282 virtual void Set(PropertyBase* property, SetCallback callback);
283 virtual void OnSet(PropertyBase* property, SetCallback callback,
284 Response* response);
285
nywang80f27162015-09-29 07:46:36 +0900286 // The synchronous version of Set().
287 // This should never be used on an interactive thread.
288 virtual bool SetAndBlock(PropertyBase* property);
289
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900290 // Update properties by reading an array of dictionary entries, each
291 // containing a string with the name and a variant with the value, from
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900292 // |message_reader|. Returns false if message is in incorrect format.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900293 bool UpdatePropertiesFromReader(MessageReader* reader);
294
295 // Updates a single property by reading a string with the name and a
296 // variant with the value from |message_reader|. Returns false if message
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900297 // is in incorrect format, or property type doesn't match.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900298 bool UpdatePropertyFromReader(MessageReader* reader);
299
300 // Calls the property changed callback passed to the constructor, used
301 // by sub-classes that do not call UpdatePropertiesFromReader() or
302 // UpdatePropertyFromReader(). Takes the |name| of the changed property.
303 void NotifyPropertyChanged(const std::string& name);
304
305 // Retrieves the object proxy this property set was initialized with,
306 // provided for sub-classes overriding methods that make D-Bus calls
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900307 // and for Property<>. Not permitted with const references to this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900308 ObjectProxy* object_proxy() { return object_proxy_; }
309
310 // Retrieves the interface of this property set.
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900311 const std::string& interface() const { return interface_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900312
313 protected:
314 // Get a weak pointer to this property set, provided so that sub-classes
315 // overriding methods that make D-Bus calls may use the existing (or
316 // override) callbacks without providing their own weak pointer factory.
317 base::WeakPtr<PropertySet> GetWeakPtr() {
318 return weak_ptr_factory_.GetWeakPtr();
319 }
320
321 private:
jpawlowski77e73fc2015-05-11 20:07:04 +0900322 // Invalidates properties by reading an array of names, from
323 // |message_reader|. Returns false if message is in incorrect format.
324 bool InvalidatePropertiesFromReader(MessageReader* reader);
325
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900326 // Pointer to object proxy for making method calls, no ownership is taken
327 // so this must outlive this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900328 ObjectProxy* object_proxy_;
329
330 // Interface of property, e.g. "org.chromium.ExampleService", this is
331 // distinct from the interface of the method call itself which is the
332 // general D-Bus Properties interface "org.freedesktop.DBus.Properties".
333 std::string interface_;
334
335 // Callback for property changes.
336 PropertyChangedCallback property_changed_callback_;
337
338 // Map of properties (as PropertyBase*) defined in the structure to
339 // names as used in D-Bus method calls and signals. The base pointer
340 // restricts property access via this map to type-unsafe and non-specific
341 // actions only.
342 typedef std::map<const std::string, PropertyBase*> PropertiesMap;
343 PropertiesMap properties_map_;
344
345 // Weak pointer factory as D-Bus callbacks may last longer than these
346 // objects.
347 base::WeakPtrFactory<PropertySet> weak_ptr_factory_;
348
349 DISALLOW_COPY_AND_ASSIGN(PropertySet);
350};
351
352// Property template, this defines the type-specific and type-safe methods
353// of properties that can be accessed as members of a PropertySet structure.
354//
355// Properties provide a cached value that has an initial sensible default
356// until the reply to PropertySet::GetAll() is retrieved and is updated by
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900357// all calls to that method, PropertySet::Get() and property changed signals
358// also handled by PropertySet. It can be obtained by calling value() on the
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900359// property.
360//
361// It is recommended that this cached value be used where necessary, with
362// code using PropertySet::PropertyChangedCallback to be notified of changes,
363// rather than incurring a round-trip to the remote object for each property
364// access.
365//
366// Where a round-trip is necessary, the Get() method is provided. And to
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900367// update the remote object value, the Set() method is also provided; these
368// both simply call methods on PropertySet.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900369//
370// Handling of particular D-Bus types is performed via specialization,
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900371// typically the PopValueFromReader() and AppendSetValueToWriter() methods
372// will need to be provided, and in rare cases a constructor to provide a
373// default value. Specializations for basic D-Bus types, strings, object
374// paths and arrays are provided for you.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900375template <class T>
tzik@chromium.org57fd8b12014-06-27 17:10:43 +0900376class CHROME_DBUS_EXPORT Property : public PropertyBase {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900377 public:
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900378 Property() {}
derat3f868a42015-07-17 00:06:44 +0900379 ~Property() override {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900380
381 // Retrieves the cached value.
keybuk@chromium.org5b48ae42012-02-17 16:46:34 +0900382 const T& value() const { return value_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900383
384 // Requests an updated value from the remote object incurring a
385 // round-trip. |callback| will be called when the new value is available.
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900386 // This may not be implemented by some interfaces.
387 virtual void Get(dbus::PropertySet::GetCallback callback) {
388 property_set()->Get(this, callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900389 }
390
nywang80f27162015-09-29 07:46:36 +0900391 // The synchronous version of Get().
392 // This should never be used on an interactive thread.
393 virtual bool GetAndBlock() {
394 return property_set()->GetAndBlock(this);
395 }
396
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900397 // Requests that the remote object change the property value to |value|,
398 // |callback| will be called to indicate the success or failure of the
399 // request, however the new value may not be available depending on the
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900400 // remote object.
401 virtual void Set(const T& value, dbus::PropertySet::SetCallback callback) {
402 set_value_ = value;
403 property_set()->Set(this, callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900404 }
405
nywang80f27162015-09-29 07:46:36 +0900406 // The synchronous version of Set().
407 // This should never be used on an interactive thread.
nywangf1196812015-09-23 09:06:40 +0900408 virtual bool SetAndBlock(const T& value) {
409 set_value_ = value;
410 return property_set()->SetAndBlock(this);
411 }
412
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900413 // Method used by PropertySet to retrieve the value from a MessageReader,
414 // no knowledge of the contained type is required, this method returns
415 // true if its expected type was found, false if not.
dtapuska95f71722015-02-10 01:02:55 +0900416 bool PopValueFromReader(MessageReader* reader) override;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900417
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900418 // Method used by PropertySet to append the set value to a MessageWriter,
419 // no knowledge of the contained type is required.
keybuk@google.comf056b962012-03-22 08:43:45 +0900420 // Implementation provided by specialization.
dmichaelbc06db42014-12-20 05:52:31 +0900421 void AppendSetValueToWriter(MessageWriter* writer) override;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900422
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900423 // Method used by test and stub implementations of dbus::PropertySet::Set
424 // to replace the property value with the set value without using a
425 // dbus::MessageReader.
dmichaelbc06db42014-12-20 05:52:31 +0900426 void ReplaceValueWithSetValue() override {
keybuk@chromium.orgc1944c62013-04-24 10:41:54 +0900427 value_ = set_value_;
428 property_set()->NotifyPropertyChanged(name());
429 }
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900430
431 // Method used by test and stub implementations to directly set the
432 // value of a property.
keybuk@chromium.orgc1944c62013-04-24 10:41:54 +0900433 void ReplaceValue(const T& value) {
434 value_ = value;
435 property_set()->NotifyPropertyChanged(name());
436 }
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900437
dtapuska95f71722015-02-10 01:02:55 +0900438 // Method used by test and stub implementations to directly set the
439 // |set_value_| of a property.
440 void ReplaceSetValueForTesting(const T& value) { set_value_ = value; }
441
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900442 private:
443 // Current cached value of the property.
444 T value_;
445
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900446 // Replacement value of the property.
447 T set_value_;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900448};
449
dcheng52b30722015-09-19 03:29:06 +0900450// Clang and GCC don't agree on how attributes should work for explicitly
451// instantiated templates. GCC ignores attributes on explicit instantiations
452// (and emits a warning) while Clang requires the visiblity attribute on the
453// explicit instantiations for them to be visible to other compilation units.
454// Hopefully clang and GCC agree one day, and this can be cleaned up:
455// https://llvm.org/bugs/show_bug.cgi?id=24815
456#pragma GCC diagnostic push
457#pragma GCC diagnostic ignored "-Wattributes"
spangcff38832015-09-15 02:49:40 +0900458
dtapuska95f71722015-02-10 01:02:55 +0900459template <>
dcheng52b30722015-09-19 03:29:06 +0900460CHROME_DBUS_EXPORT Property<uint8>::Property();
461template <>
462CHROME_DBUS_EXPORT bool Property<uint8>::PopValueFromReader(
dtapuska95f71722015-02-10 01:02:55 +0900463 MessageReader* reader);
464template <>
dcheng52b30722015-09-19 03:29:06 +0900465CHROME_DBUS_EXPORT void Property<uint8>::AppendSetValueToWriter(
dtapuska95f71722015-02-10 01:02:55 +0900466 MessageWriter* writer);
dcheng52b30722015-09-19 03:29:06 +0900467extern template class CHROME_DBUS_EXPORT Property<uint8>;
dtapuska95f71722015-02-10 01:02:55 +0900468
469template <>
dcheng52b30722015-09-19 03:29:06 +0900470CHROME_DBUS_EXPORT Property<bool>::Property();
471template <>
472CHROME_DBUS_EXPORT bool Property<bool>::PopValueFromReader(
473 MessageReader* reader);
474template <>
475CHROME_DBUS_EXPORT void Property<bool>::AppendSetValueToWriter(
476 MessageWriter* writer);
477extern template class CHROME_DBUS_EXPORT Property<bool>;
478
479template <>
480CHROME_DBUS_EXPORT Property<int16>::Property();
481template <>
482CHROME_DBUS_EXPORT bool Property<int16>::PopValueFromReader(
483 MessageReader* reader);
484template <>
485CHROME_DBUS_EXPORT void Property<int16>::AppendSetValueToWriter(
486 MessageWriter* writer);
487extern template class CHROME_DBUS_EXPORT Property<int16>;
488
489template <>
490CHROME_DBUS_EXPORT Property<uint16>::Property();
491template <>
492CHROME_DBUS_EXPORT bool Property<uint16>::PopValueFromReader(
493 MessageReader* reader);
494template <>
495CHROME_DBUS_EXPORT void Property<uint16>::AppendSetValueToWriter(
496 MessageWriter* writer);
497extern template class CHROME_DBUS_EXPORT Property<uint16>;
498
499template <>
500CHROME_DBUS_EXPORT Property<int32>::Property();
501template <>
502CHROME_DBUS_EXPORT bool Property<int32>::PopValueFromReader(
503 MessageReader* reader);
504template <>
505CHROME_DBUS_EXPORT void Property<int32>::AppendSetValueToWriter(
506 MessageWriter* writer);
507extern template class CHROME_DBUS_EXPORT Property<int32>;
508
509template <>
510CHROME_DBUS_EXPORT Property<uint32>::Property();
511template <>
512CHROME_DBUS_EXPORT bool Property<uint32>::PopValueFromReader(
513 MessageReader* reader);
514template <>
515CHROME_DBUS_EXPORT void Property<uint32>::AppendSetValueToWriter(
516 MessageWriter* writer);
517extern template class CHROME_DBUS_EXPORT Property<uint32>;
518
519template <>
520CHROME_DBUS_EXPORT Property<int64>::Property();
521template <>
522CHROME_DBUS_EXPORT bool Property<int64>::PopValueFromReader(
523 MessageReader* reader);
524template <>
525CHROME_DBUS_EXPORT void Property<int64>::AppendSetValueToWriter(
526 MessageWriter* writer);
527extern template class CHROME_DBUS_EXPORT Property<int64>;
528
529template <>
530CHROME_DBUS_EXPORT Property<uint64>::Property();
531template <>
532CHROME_DBUS_EXPORT bool Property<uint64>::PopValueFromReader(
533 MessageReader* reader);
534template <>
535CHROME_DBUS_EXPORT void Property<uint64>::AppendSetValueToWriter(
536 MessageWriter* writer);
537extern template class CHROME_DBUS_EXPORT Property<uint64>;
538
539template <>
540CHROME_DBUS_EXPORT Property<double>::Property();
541template <>
542CHROME_DBUS_EXPORT bool Property<double>::PopValueFromReader(
543 MessageReader* reader);
544template <>
545CHROME_DBUS_EXPORT void Property<double>::AppendSetValueToWriter(
546 MessageWriter* writer);
547extern template class CHROME_DBUS_EXPORT Property<double>;
548
549template <>
550CHROME_DBUS_EXPORT bool Property<std::string>::PopValueFromReader(
551 MessageReader* reader);
552template <>
553CHROME_DBUS_EXPORT void Property<std::string>::AppendSetValueToWriter(
554 MessageWriter* writer);
555extern template class CHROME_DBUS_EXPORT Property<std::string>;
556
557template <>
558CHROME_DBUS_EXPORT bool Property<ObjectPath>::PopValueFromReader(
559 MessageReader* reader);
560template <>
561CHROME_DBUS_EXPORT void Property<ObjectPath>::AppendSetValueToWriter(
562 MessageWriter* writer);
563extern template class CHROME_DBUS_EXPORT Property<ObjectPath>;
564
565template <>
566CHROME_DBUS_EXPORT bool Property<std::vector<std::string>>::PopValueFromReader(
567 MessageReader* reader);
568template <>
569CHROME_DBUS_EXPORT void Property<
570 std::vector<std::string>>::AppendSetValueToWriter(MessageWriter* writer);
571extern template class CHROME_DBUS_EXPORT Property<std::vector<std::string>>;
572
573template <>
574CHROME_DBUS_EXPORT bool Property<std::vector<ObjectPath>>::PopValueFromReader(
575 MessageReader* reader);
576template <>
577CHROME_DBUS_EXPORT void Property<
578 std::vector<ObjectPath>>::AppendSetValueToWriter(MessageWriter* writer);
579extern template class CHROME_DBUS_EXPORT Property<std::vector<ObjectPath>>;
580
581template <>
582CHROME_DBUS_EXPORT bool Property<std::vector<uint8>>::PopValueFromReader(
583 MessageReader* reader);
584template <>
585CHROME_DBUS_EXPORT void Property<std::vector<uint8>>::AppendSetValueToWriter(
586 MessageWriter* writer);
587extern template class CHROME_DBUS_EXPORT Property<std::vector<uint8>>;
588
589template <>
590CHROME_DBUS_EXPORT bool
591Property<std::map<std::string, std::string>>::PopValueFromReader(
592 MessageReader* reader);
593template <>
594CHROME_DBUS_EXPORT void
595Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
596 MessageWriter* writer);
597extern template class CHROME_DBUS_EXPORT
598 Property<std::map<std::string, std::string>>;
599
600template <>
601CHROME_DBUS_EXPORT bool
602Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
dtapuska95f71722015-02-10 01:02:55 +0900603 PopValueFromReader(MessageReader* reader);
604template <>
dcheng52b30722015-09-19 03:29:06 +0900605CHROME_DBUS_EXPORT void
606Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
dtapuska95f71722015-02-10 01:02:55 +0900607 AppendSetValueToWriter(MessageWriter* writer);
dcheng52b30722015-09-19 03:29:06 +0900608extern template class CHROME_DBUS_EXPORT
609 Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
610
611#pragma GCC diagnostic pop
dtapuska95f71722015-02-10 01:02:55 +0900612
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900613} // namespace dbus
614
615#endif // DBUS_PROPERTY_H_