blob: 4d92a7fd94f0daee8b5a6b85f6565dd386e28f18 [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
avi0ad0ce02015-12-23 03:12:45 +09008#include <stdint.h>
9
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090010#include <map>
11#include <string>
puthik90fd20c2016-10-06 14:03:03 +090012#include <unordered_map>
dtapuska95f71722015-02-10 01:02:55 +090013#include <utility>
14#include <vector>
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090015
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090016#include "base/bind.h"
17#include "base/callback.h"
avi0ad0ce02015-12-23 03:12:45 +090018#include "base/macros.h"
tfarina@chromium.org7928ea22012-11-05 10:56:14 +090019#include "dbus/dbus_export.h"
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090020#include "dbus/message.h"
21#include "dbus/object_proxy.h"
22
23// D-Bus objects frequently provide sets of properties accessed via a
24// standard interface of method calls and signals to obtain the current value,
25// set a new value and be notified of changes to the value. Unfortunately this
26// interface makes heavy use of variants and dictionaries of variants. The
27// classes defined here make dealing with properties in a type-safe manner
28// possible.
29//
30// Client implementation classes should define a Properties structure, deriving
31// from the PropertySet class defined here. This structure should contain a
32// member for each property defined as an instance of the Property<> class,
33// specifying the type to the template. Finally the structure should chain up
34// to the PropertySet constructor, and then call RegisterProperty() for each
35// property defined to associate them with their string name.
36//
37// Example:
38// class ExampleClient {
39// public:
40// struct Properties : public dbus::PropertySet {
41// dbus::Property<std::string> name;
avi0ad0ce02015-12-23 03:12:45 +090042// dbus::Property<uint16_t> version;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090043// dbus::Property<dbus::ObjectPath> parent;
Ben Chandf19e682017-11-08 10:50:21 +090044// dbus::Property<std::vector<std::string>> children;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090045//
46// Properties(dbus::ObjectProxy* object_proxy,
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +090047// const PropertyChangedCallback callback)
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090048// : dbus::PropertySet(object_proxy, "com.example.DBus", callback) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090049// RegisterProperty("Name", &name);
50// RegisterProperty("Version", &version);
51// RegisterProperty("Parent", &parent);
52// RegisterProperty("Children", &children);
53// }
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090054// virtual ~Properties() {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090055// };
56//
57// The Properties structure requires a pointer to the object proxy of the
58// actual object to track, and after construction should have signals
59// connected to that object and initial values set by calling ConnectSignals()
60// and GetAll(). The structure should not outlive the object proxy, so it
61// is recommended that the lifecycle of both be managed together.
62//
63// Example (continued):
64//
Ben Chandf19e682017-11-08 10:50:21 +090065// typedef std::map<std::pair<dbus::ObjectProxy*, Properties*>> Object;
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090066// typedef std::map<dbus::ObjectPath, Object> ObjectMap;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090067// ObjectMap object_map_;
68//
69// dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path) {
70// return GetObject(object_path).first;
71// }
72//
73// Properties* GetProperties(const dbus::ObjectPath& object_path) {
74// return GetObject(object_path).second;
75// }
76//
77// Object GetObject(const dbus::ObjectPath& object_path) {
78// ObjectMap::iterator it = object_map_.find(object_path);
79// if (it != object_map_.end())
80// return it->second;
81//
82// dbus::ObjectProxy* object_proxy = bus->GetObjectProxy(...);
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090083// // connect signals, etc.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090084//
85// Properties* properties = new Properties(
86// object_proxy,
87// base::Bind(&PropertyChanged,
88// weak_ptr_factory_.GetWeakPtr(),
89// object_path));
90// properties->ConnectSignals();
91// properties->GetAll();
92//
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +090093// Object object = std::make_pair(object_proxy, properties);
94// object_map_[object_path] = object;
95// return object;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090096// }
97// };
98//
99// This now allows code using the client implementation to access properties
100// in a type-safe manner, and assuming the PropertyChanged callback is
101// propogated up to observers, be notified of changes. A typical access of
102// the current value of the name property would be:
103//
104// ExampleClient::Properties* p = example_client->GetProperties(object_path);
105// std::string name = p->name.value();
106//
107// Normally these values are updated from signals emitted by the remote object,
108// in case an explicit round-trip is needed to obtain the current value, the
109// Get() method can be used and indicates whether or not the value update was
110// successful. The updated value can be obtained in the callback using the
111// value() method.
112//
113// p->children.Get(base::Bind(&OnGetChildren));
114//
115// A new value can be set using the Set() method, the callback indicates
116// success only; it is up to the remote object when (and indeed if) it updates
117// the property value, and whether it emits a signal or a Get() call is
118// required to obtain it.
119//
120// p->version.Set(20, base::Bind(&OnSetVersion))
121
122namespace dbus {
123
124// D-Bus Properties interface constants, declared here rather than
125// in property.cc because template methods use them.
126const char kPropertiesInterface[] = "org.freedesktop.DBus.Properties";
127const char kPropertiesGetAll[] = "GetAll";
128const char kPropertiesGet[] = "Get";
129const char kPropertiesSet[] = "Set";
130const char kPropertiesChanged[] = "PropertiesChanged";
131
132class PropertySet;
133
134// PropertyBase is an abstract base-class consisting of the parts of
135// the Property<> template that are not type-specific, such as the
136// associated PropertySet, property name, and the type-unsafe parts
137// used by PropertySet.
derat3f868a42015-07-17 00:06:44 +0900138class CHROME_DBUS_EXPORT PropertyBase {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900139 public:
derat3f868a42015-07-17 00:06:44 +0900140 PropertyBase();
141 virtual ~PropertyBase();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900142
143 // Initializes the |property_set| and property |name| so that method
144 // calls may be made from this class. This method is called by
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900145 // PropertySet::RegisterProperty() passing |this| for |property_set| so
146 // there should be no need to call it directly. If you do beware that
147 // no ownership or reference to |property_set| is taken so that object
148 // must outlive this one.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900149 void Init(PropertySet* property_set, const std::string& name);
150
151 // Retrieves the name of this property, this may be useful in observers
152 // to avoid specifying the name in more than once place, e.g.
153 //
154 // void Client::PropertyChanged(const dbus::ObjectPath& object_path,
155 // const std::string &property_name) {
156 // Properties& properties = GetProperties(object_path);
157 // if (property_name == properties.version.name()) {
158 // // Handle version property changing
159 // }
160 // }
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900161 const std::string& name() const { return name_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900162
jpawlowski77e73fc2015-05-11 20:07:04 +0900163 // Returns true if property is valid, false otherwise.
164 bool is_valid() const { return is_valid_; }
165
166 // Allows to mark Property as valid or invalid.
167 void set_valid(bool is_valid) { is_valid_ = is_valid; }
168
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900169 // Method used by PropertySet to retrieve the value from a MessageReader,
170 // no knowledge of the contained type is required, this method returns
171 // true if its expected type was found, false if not.
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900172 // Implementation provided by specialization.
dtapuska95f71722015-02-10 01:02:55 +0900173 virtual bool PopValueFromReader(MessageReader* reader) = 0;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900174
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900175 // Method used by PropertySet to append the set value to a MessageWriter,
176 // no knowledge of the contained type is required.
177 // Implementation provided by specialization.
178 virtual void AppendSetValueToWriter(MessageWriter* writer) = 0;
179
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900180 // Method used by test and stub implementations of dbus::PropertySet::Set
181 // to replace the property value with the set value without using a
182 // dbus::MessageReader.
183 virtual void ReplaceValueWithSetValue() = 0;
184
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900185 protected:
186 // Retrieves the associated property set.
187 PropertySet* property_set() { return property_set_; }
188
189 private:
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900190 // Pointer to the PropertySet instance that this instance is a member of,
191 // no ownership is taken and |property_set_| must outlive this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900192 PropertySet* property_set_;
193
jpawlowski77e73fc2015-05-11 20:07:04 +0900194 bool is_valid_;
195
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900196 // Name of the property.
197 std::string name_;
198
199 DISALLOW_COPY_AND_ASSIGN(PropertyBase);
200};
201
202// PropertySet groups a collection of properties for a remote object
203// together into a single structure, fixing their types and name such
204// that calls made through it are type-safe.
205//
206// Clients always sub-class this to add the properties, and should always
207// provide a constructor that chains up to this and then calls
208// RegisterProperty() for each property defined.
209//
210// After creation, client code should call ConnectSignals() and most likely
211// GetAll() to seed initial values and update as changes occur.
tfarina@chromium.org7928ea22012-11-05 10:56:14 +0900212class CHROME_DBUS_EXPORT PropertySet {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900213 public:
214 // Callback for changes to cached values of properties, either notified
215 // via signal, or as a result of calls to Get() and GetAll(). The |name|
216 // argument specifies the name of the property changed.
217 typedef base::Callback<void(const std::string& name)> PropertyChangedCallback;
218
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900219 // Constructs a property set, where |object_proxy| specifies the proxy for
220 // the/ remote object that these properties are for, care should be taken to
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900221 // ensure that this object does not outlive the lifetime of the proxy;
222 // |interface| specifies the D-Bus interface of these properties, and
223 // |property_changed_callback| specifies the callback for when properties
224 // are changed, this may be a NULL callback.
225 PropertySet(ObjectProxy* object_proxy, const std::string& interface,
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900226 const PropertyChangedCallback& property_changed_callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900227
228 // Destructor; we don't hold on to any references or memory that needs
229 // explicit clean-up, but clang thinks we might.
keybuk@chromium.org82e082a2012-02-17 10:01:18 +0900230 virtual ~PropertySet();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900231
232 // Registers a property, generally called from the subclass constructor;
233 // pass the |name| of the property as used in method calls and signals,
234 // and the pointer to the |property| member of the structure. This will
235 // call the PropertyBase::Init method.
236 void RegisterProperty(const std::string& name, PropertyBase* property);
237
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900238 // Connects property change notification signals to the object, generally
239 // called immediately after the object is created and before calls to other
240 // methods. Sub-classes may override to use different D-Bus signals.
241 virtual void ConnectSignals();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900242
243 // Methods connected by ConnectSignals() and called by dbus:: when
244 // a property is changed. Sub-classes may override if the property
245 // changed signal provides different arguments.
dtapuska95f71722015-02-10 01:02:55 +0900246 virtual void ChangedReceived(Signal* signal);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900247 virtual void ChangedConnected(const std::string& interface_name,
248 const std::string& signal_name,
249 bool success);
250
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900251 // Callback for Get() method, |success| indicates whether or not the
252 // value could be retrived, if true the new value can be obtained by
253 // calling value() on the property.
254 typedef base::Callback<void(bool success)> GetCallback;
255
256 // Requests an updated value from the remote object for |property|
257 // incurring a round-trip. |callback| will be called when the new
258 // value is available. This may not be implemented by some interfaces,
259 // and may be overriden by sub-classes if interfaces use different
260 // method calls.
261 virtual void Get(PropertyBase* property, GetCallback callback);
262 virtual void OnGet(PropertyBase* property, GetCallback callback,
263 Response* response);
264
nywang80f27162015-09-29 07:46:36 +0900265 // The synchronous version of Get().
266 // This should never be used on an interactive thread.
267 virtual bool GetAndBlock(PropertyBase* property);
268
keybuk@chromium.orgf63debc2012-02-18 01:50:42 +0900269 // Queries the remote object for values of all properties and updates
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900270 // initial values. Sub-classes may override to use a different D-Bus
271 // method, or if the remote object does not support retrieving all
272 // properties, either ignore or obtain each property value individually.
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900273 virtual void GetAll();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900274 virtual void OnGetAll(Response* response);
275
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900276 // Callback for Set() method, |success| indicates whether or not the
277 // new property value was accepted by the remote object.
278 typedef base::Callback<void(bool success)> SetCallback;
279
280 // Requests that the remote object for |property| change the property to
281 // its new value. |callback| will be called to indicate the success or
282 // failure of the request, however the new value may not be available
283 // depending on the remote object. This method may be overridden by
284 // sub-classes if interfaces use different method calls.
285 virtual void Set(PropertyBase* property, SetCallback callback);
286 virtual void OnSet(PropertyBase* property, SetCallback callback,
287 Response* response);
288
nywang80f27162015-09-29 07:46:36 +0900289 // The synchronous version of Set().
290 // This should never be used on an interactive thread.
291 virtual bool SetAndBlock(PropertyBase* property);
292
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900293 // Update properties by reading an array of dictionary entries, each
294 // containing a string with the name and a variant with the value, from
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900295 // |message_reader|. Returns false if message is in incorrect format.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900296 bool UpdatePropertiesFromReader(MessageReader* reader);
297
298 // Updates a single property by reading a string with the name and a
299 // variant with the value from |message_reader|. Returns false if message
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900300 // is in incorrect format, or property type doesn't match.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900301 bool UpdatePropertyFromReader(MessageReader* reader);
302
303 // Calls the property changed callback passed to the constructor, used
304 // by sub-classes that do not call UpdatePropertiesFromReader() or
305 // UpdatePropertyFromReader(). Takes the |name| of the changed property.
306 void NotifyPropertyChanged(const std::string& name);
307
308 // Retrieves the object proxy this property set was initialized with,
309 // provided for sub-classes overriding methods that make D-Bus calls
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900310 // and for Property<>. Not permitted with const references to this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900311 ObjectProxy* object_proxy() { return object_proxy_; }
312
313 // Retrieves the interface of this property set.
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900314 const std::string& interface() const { return interface_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900315
316 protected:
317 // Get a weak pointer to this property set, provided so that sub-classes
318 // overriding methods that make D-Bus calls may use the existing (or
319 // override) callbacks without providing their own weak pointer factory.
320 base::WeakPtr<PropertySet> GetWeakPtr() {
321 return weak_ptr_factory_.GetWeakPtr();
322 }
323
324 private:
jpawlowski77e73fc2015-05-11 20:07:04 +0900325 // Invalidates properties by reading an array of names, from
326 // |message_reader|. Returns false if message is in incorrect format.
327 bool InvalidatePropertiesFromReader(MessageReader* reader);
328
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900329 // Pointer to object proxy for making method calls, no ownership is taken
330 // so this must outlive this class.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900331 ObjectProxy* object_proxy_;
332
333 // Interface of property, e.g. "org.chromium.ExampleService", this is
334 // distinct from the interface of the method call itself which is the
335 // general D-Bus Properties interface "org.freedesktop.DBus.Properties".
336 std::string interface_;
337
338 // Callback for property changes.
339 PropertyChangedCallback property_changed_callback_;
340
341 // Map of properties (as PropertyBase*) defined in the structure to
342 // names as used in D-Bus method calls and signals. The base pointer
343 // restricts property access via this map to type-unsafe and non-specific
344 // actions only.
345 typedef std::map<const std::string, PropertyBase*> PropertiesMap;
346 PropertiesMap properties_map_;
347
348 // Weak pointer factory as D-Bus callbacks may last longer than these
349 // objects.
350 base::WeakPtrFactory<PropertySet> weak_ptr_factory_;
351
352 DISALLOW_COPY_AND_ASSIGN(PropertySet);
353};
354
355// Property template, this defines the type-specific and type-safe methods
356// of properties that can be accessed as members of a PropertySet structure.
357//
358// Properties provide a cached value that has an initial sensible default
359// until the reply to PropertySet::GetAll() is retrieved and is updated by
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900360// all calls to that method, PropertySet::Get() and property changed signals
361// also handled by PropertySet. It can be obtained by calling value() on the
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900362// property.
363//
364// It is recommended that this cached value be used where necessary, with
365// code using PropertySet::PropertyChangedCallback to be notified of changes,
366// rather than incurring a round-trip to the remote object for each property
367// access.
368//
369// Where a round-trip is necessary, the Get() method is provided. And to
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900370// update the remote object value, the Set() method is also provided; these
371// both simply call methods on PropertySet.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900372//
373// Handling of particular D-Bus types is performed via specialization,
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900374// typically the PopValueFromReader() and AppendSetValueToWriter() methods
375// will need to be provided, and in rare cases a constructor to provide a
376// default value. Specializations for basic D-Bus types, strings, object
377// paths and arrays are provided for you.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900378template <class T>
tzik@chromium.org57fd8b12014-06-27 17:10:43 +0900379class CHROME_DBUS_EXPORT Property : public PropertyBase {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900380 public:
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900381 Property() {}
derat3f868a42015-07-17 00:06:44 +0900382 ~Property() override {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900383
384 // Retrieves the cached value.
keybuk@chromium.org5b48ae42012-02-17 16:46:34 +0900385 const T& value() const { return value_; }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900386
387 // Requests an updated value from the remote object incurring a
388 // round-trip. |callback| will be called when the new value is available.
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900389 // This may not be implemented by some interfaces.
390 virtual void Get(dbus::PropertySet::GetCallback callback) {
391 property_set()->Get(this, callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900392 }
393
nywang80f27162015-09-29 07:46:36 +0900394 // The synchronous version of Get().
395 // This should never be used on an interactive thread.
396 virtual bool GetAndBlock() {
397 return property_set()->GetAndBlock(this);
398 }
399
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900400 // Requests that the remote object change the property value to |value|,
401 // |callback| will be called to indicate the success or failure of the
402 // request, however the new value may not be available depending on the
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900403 // remote object.
404 virtual void Set(const T& value, dbus::PropertySet::SetCallback callback) {
405 set_value_ = value;
406 property_set()->Set(this, callback);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900407 }
408
nywang80f27162015-09-29 07:46:36 +0900409 // The synchronous version of Set().
410 // This should never be used on an interactive thread.
nywangf1196812015-09-23 09:06:40 +0900411 virtual bool SetAndBlock(const T& value) {
412 set_value_ = value;
413 return property_set()->SetAndBlock(this);
414 }
415
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900416 // Method used by PropertySet to retrieve the value from a MessageReader,
417 // no knowledge of the contained type is required, this method returns
418 // true if its expected type was found, false if not.
dtapuska95f71722015-02-10 01:02:55 +0900419 bool PopValueFromReader(MessageReader* reader) override;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900420
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900421 // Method used by PropertySet to append the set value to a MessageWriter,
422 // no knowledge of the contained type is required.
keybuk@google.comf056b962012-03-22 08:43:45 +0900423 // Implementation provided by specialization.
dmichaelbc06db42014-12-20 05:52:31 +0900424 void AppendSetValueToWriter(MessageWriter* writer) override;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900425
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900426 // Method used by test and stub implementations of dbus::PropertySet::Set
427 // to replace the property value with the set value without using a
428 // dbus::MessageReader.
dmichaelbc06db42014-12-20 05:52:31 +0900429 void ReplaceValueWithSetValue() override {
keybuk@chromium.orgc1944c62013-04-24 10:41:54 +0900430 value_ = set_value_;
431 property_set()->NotifyPropertyChanged(name());
432 }
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900433
434 // Method used by test and stub implementations to directly set the
435 // value of a property.
keybuk@chromium.orgc1944c62013-04-24 10:41:54 +0900436 void ReplaceValue(const T& value) {
437 value_ = value;
438 property_set()->NotifyPropertyChanged(name());
439 }
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +0900440
dtapuska95f71722015-02-10 01:02:55 +0900441 // Method used by test and stub implementations to directly set the
442 // |set_value_| of a property.
443 void ReplaceSetValueForTesting(const T& value) { set_value_ = value; }
444
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900445 private:
446 // Current cached value of the property.
447 T value_;
448
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900449 // Replacement value of the property.
450 T set_value_;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900451};
452
dcheng52b30722015-09-19 03:29:06 +0900453// Clang and GCC don't agree on how attributes should work for explicitly
454// instantiated templates. GCC ignores attributes on explicit instantiations
455// (and emits a warning) while Clang requires the visiblity attribute on the
456// explicit instantiations for them to be visible to other compilation units.
457// Hopefully clang and GCC agree one day, and this can be cleaned up:
458// https://llvm.org/bugs/show_bug.cgi?id=24815
459#pragma GCC diagnostic push
460#pragma GCC diagnostic ignored "-Wattributes"
spangcff38832015-09-15 02:49:40 +0900461
dtapuska95f71722015-02-10 01:02:55 +0900462template <>
avi0ad0ce02015-12-23 03:12:45 +0900463CHROME_DBUS_EXPORT Property<uint8_t>::Property();
dcheng52b30722015-09-19 03:29:06 +0900464template <>
avi0ad0ce02015-12-23 03:12:45 +0900465CHROME_DBUS_EXPORT bool Property<uint8_t>::PopValueFromReader(
dtapuska95f71722015-02-10 01:02:55 +0900466 MessageReader* reader);
467template <>
avi0ad0ce02015-12-23 03:12:45 +0900468CHROME_DBUS_EXPORT void Property<uint8_t>::AppendSetValueToWriter(
dtapuska95f71722015-02-10 01:02:55 +0900469 MessageWriter* writer);
avi0ad0ce02015-12-23 03:12:45 +0900470extern template class CHROME_DBUS_EXPORT Property<uint8_t>;
dtapuska95f71722015-02-10 01:02:55 +0900471
472template <>
dcheng52b30722015-09-19 03:29:06 +0900473CHROME_DBUS_EXPORT Property<bool>::Property();
474template <>
475CHROME_DBUS_EXPORT bool Property<bool>::PopValueFromReader(
476 MessageReader* reader);
477template <>
478CHROME_DBUS_EXPORT void Property<bool>::AppendSetValueToWriter(
479 MessageWriter* writer);
480extern template class CHROME_DBUS_EXPORT Property<bool>;
481
482template <>
avi0ad0ce02015-12-23 03:12:45 +0900483CHROME_DBUS_EXPORT Property<int16_t>::Property();
dcheng52b30722015-09-19 03:29:06 +0900484template <>
avi0ad0ce02015-12-23 03:12:45 +0900485CHROME_DBUS_EXPORT bool Property<int16_t>::PopValueFromReader(
dcheng52b30722015-09-19 03:29:06 +0900486 MessageReader* reader);
487template <>
avi0ad0ce02015-12-23 03:12:45 +0900488CHROME_DBUS_EXPORT void Property<int16_t>::AppendSetValueToWriter(
dcheng52b30722015-09-19 03:29:06 +0900489 MessageWriter* writer);
avi0ad0ce02015-12-23 03:12:45 +0900490extern template class CHROME_DBUS_EXPORT Property<int16_t>;
dcheng52b30722015-09-19 03:29:06 +0900491
492template <>
avi0ad0ce02015-12-23 03:12:45 +0900493CHROME_DBUS_EXPORT Property<uint16_t>::Property();
dcheng52b30722015-09-19 03:29:06 +0900494template <>
avi0ad0ce02015-12-23 03:12:45 +0900495CHROME_DBUS_EXPORT bool Property<uint16_t>::PopValueFromReader(
dcheng52b30722015-09-19 03:29:06 +0900496 MessageReader* reader);
497template <>
avi0ad0ce02015-12-23 03:12:45 +0900498CHROME_DBUS_EXPORT void Property<uint16_t>::AppendSetValueToWriter(
dcheng52b30722015-09-19 03:29:06 +0900499 MessageWriter* writer);
avi0ad0ce02015-12-23 03:12:45 +0900500extern template class CHROME_DBUS_EXPORT Property<uint16_t>;
dcheng52b30722015-09-19 03:29:06 +0900501
502template <>
avi0ad0ce02015-12-23 03:12:45 +0900503CHROME_DBUS_EXPORT Property<int32_t>::Property();
dcheng52b30722015-09-19 03:29:06 +0900504template <>
avi0ad0ce02015-12-23 03:12:45 +0900505CHROME_DBUS_EXPORT bool Property<int32_t>::PopValueFromReader(
dcheng52b30722015-09-19 03:29:06 +0900506 MessageReader* reader);
507template <>
avi0ad0ce02015-12-23 03:12:45 +0900508CHROME_DBUS_EXPORT void Property<int32_t>::AppendSetValueToWriter(
dcheng52b30722015-09-19 03:29:06 +0900509 MessageWriter* writer);
avi0ad0ce02015-12-23 03:12:45 +0900510extern template class CHROME_DBUS_EXPORT Property<int32_t>;
dcheng52b30722015-09-19 03:29:06 +0900511
512template <>
avi0ad0ce02015-12-23 03:12:45 +0900513CHROME_DBUS_EXPORT Property<uint32_t>::Property();
dcheng52b30722015-09-19 03:29:06 +0900514template <>
avi0ad0ce02015-12-23 03:12:45 +0900515CHROME_DBUS_EXPORT bool Property<uint32_t>::PopValueFromReader(
dcheng52b30722015-09-19 03:29:06 +0900516 MessageReader* reader);
517template <>
avi0ad0ce02015-12-23 03:12:45 +0900518CHROME_DBUS_EXPORT void Property<uint32_t>::AppendSetValueToWriter(
dcheng52b30722015-09-19 03:29:06 +0900519 MessageWriter* writer);
avi0ad0ce02015-12-23 03:12:45 +0900520extern template class CHROME_DBUS_EXPORT Property<uint32_t>;
dcheng52b30722015-09-19 03:29:06 +0900521
522template <>
avi0ad0ce02015-12-23 03:12:45 +0900523CHROME_DBUS_EXPORT Property<int64_t>::Property();
dcheng52b30722015-09-19 03:29:06 +0900524template <>
avi0ad0ce02015-12-23 03:12:45 +0900525CHROME_DBUS_EXPORT bool Property<int64_t>::PopValueFromReader(
dcheng52b30722015-09-19 03:29:06 +0900526 MessageReader* reader);
527template <>
avi0ad0ce02015-12-23 03:12:45 +0900528CHROME_DBUS_EXPORT void Property<int64_t>::AppendSetValueToWriter(
dcheng52b30722015-09-19 03:29:06 +0900529 MessageWriter* writer);
avi0ad0ce02015-12-23 03:12:45 +0900530extern template class CHROME_DBUS_EXPORT Property<int64_t>;
dcheng52b30722015-09-19 03:29:06 +0900531
532template <>
avi0ad0ce02015-12-23 03:12:45 +0900533CHROME_DBUS_EXPORT Property<uint64_t>::Property();
dcheng52b30722015-09-19 03:29:06 +0900534template <>
avi0ad0ce02015-12-23 03:12:45 +0900535CHROME_DBUS_EXPORT bool Property<uint64_t>::PopValueFromReader(
dcheng52b30722015-09-19 03:29:06 +0900536 MessageReader* reader);
537template <>
avi0ad0ce02015-12-23 03:12:45 +0900538CHROME_DBUS_EXPORT void Property<uint64_t>::AppendSetValueToWriter(
dcheng52b30722015-09-19 03:29:06 +0900539 MessageWriter* writer);
avi0ad0ce02015-12-23 03:12:45 +0900540extern template class CHROME_DBUS_EXPORT Property<uint64_t>;
dcheng52b30722015-09-19 03:29:06 +0900541
542template <>
543CHROME_DBUS_EXPORT Property<double>::Property();
544template <>
545CHROME_DBUS_EXPORT bool Property<double>::PopValueFromReader(
546 MessageReader* reader);
547template <>
548CHROME_DBUS_EXPORT void Property<double>::AppendSetValueToWriter(
549 MessageWriter* writer);
550extern template class CHROME_DBUS_EXPORT Property<double>;
551
552template <>
553CHROME_DBUS_EXPORT bool Property<std::string>::PopValueFromReader(
554 MessageReader* reader);
555template <>
556CHROME_DBUS_EXPORT void Property<std::string>::AppendSetValueToWriter(
557 MessageWriter* writer);
558extern template class CHROME_DBUS_EXPORT Property<std::string>;
559
560template <>
561CHROME_DBUS_EXPORT bool Property<ObjectPath>::PopValueFromReader(
562 MessageReader* reader);
563template <>
564CHROME_DBUS_EXPORT void Property<ObjectPath>::AppendSetValueToWriter(
565 MessageWriter* writer);
566extern template class CHROME_DBUS_EXPORT Property<ObjectPath>;
567
568template <>
569CHROME_DBUS_EXPORT bool Property<std::vector<std::string>>::PopValueFromReader(
570 MessageReader* reader);
571template <>
572CHROME_DBUS_EXPORT void Property<
573 std::vector<std::string>>::AppendSetValueToWriter(MessageWriter* writer);
574extern template class CHROME_DBUS_EXPORT Property<std::vector<std::string>>;
575
576template <>
577CHROME_DBUS_EXPORT bool Property<std::vector<ObjectPath>>::PopValueFromReader(
578 MessageReader* reader);
579template <>
580CHROME_DBUS_EXPORT void Property<
581 std::vector<ObjectPath>>::AppendSetValueToWriter(MessageWriter* writer);
582extern template class CHROME_DBUS_EXPORT Property<std::vector<ObjectPath>>;
583
584template <>
avi0ad0ce02015-12-23 03:12:45 +0900585CHROME_DBUS_EXPORT bool Property<std::vector<uint8_t>>::PopValueFromReader(
dcheng52b30722015-09-19 03:29:06 +0900586 MessageReader* reader);
587template <>
avi0ad0ce02015-12-23 03:12:45 +0900588CHROME_DBUS_EXPORT void Property<std::vector<uint8_t>>::AppendSetValueToWriter(
dcheng52b30722015-09-19 03:29:06 +0900589 MessageWriter* writer);
avi0ad0ce02015-12-23 03:12:45 +0900590extern template class CHROME_DBUS_EXPORT Property<std::vector<uint8_t>>;
dcheng52b30722015-09-19 03:29:06 +0900591
592template <>
593CHROME_DBUS_EXPORT bool
594Property<std::map<std::string, std::string>>::PopValueFromReader(
595 MessageReader* reader);
596template <>
597CHROME_DBUS_EXPORT void
598Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
599 MessageWriter* writer);
600extern template class CHROME_DBUS_EXPORT
601 Property<std::map<std::string, std::string>>;
602
603template <>
604CHROME_DBUS_EXPORT bool
605Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
dtapuska95f71722015-02-10 01:02:55 +0900606 PopValueFromReader(MessageReader* reader);
607template <>
dcheng52b30722015-09-19 03:29:06 +0900608CHROME_DBUS_EXPORT void
609Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
dtapuska95f71722015-02-10 01:02:55 +0900610 AppendSetValueToWriter(MessageWriter* writer);
dcheng52b30722015-09-19 03:29:06 +0900611extern template class CHROME_DBUS_EXPORT
612 Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
613
puthik90fd20c2016-10-06 14:03:03 +0900614template <>
615CHROME_DBUS_EXPORT bool
616Property<std::unordered_map<std::string, std::vector<uint8_t>>>::
617 PopValueFromReader(MessageReader* reader);
618template <>
619CHROME_DBUS_EXPORT void
620Property<std::unordered_map<std::string, std::vector<uint8_t>>>::
621 AppendSetValueToWriter(MessageWriter* writer);
622extern template class CHROME_DBUS_EXPORT
623 Property<std::unordered_map<std::string, std::vector<uint8_t>>>;
624
puthik6558aab2016-11-05 04:38:17 +0900625template <>
626CHROME_DBUS_EXPORT bool
627Property<std::unordered_map<uint16_t, std::vector<uint8_t>>>::
628 PopValueFromReader(MessageReader* reader);
629template <>
630CHROME_DBUS_EXPORT void
631Property<std::unordered_map<uint16_t, std::vector<uint8_t>>>::
632 AppendSetValueToWriter(MessageWriter* writer);
633extern template class CHROME_DBUS_EXPORT
634 Property<std::unordered_map<uint16_t, std::vector<uint8_t>>>;
635
dcheng52b30722015-09-19 03:29:06 +0900636#pragma GCC diagnostic pop
dtapuska95f71722015-02-10 01:02:55 +0900637
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900638} // namespace dbus
639
640#endif // DBUS_PROPERTY_H_