property.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef DBUS_PROPERTY_H_
  5. #define DBUS_PROPERTY_H_
  6. #include <stdint.h>
  7. #include <map>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include "base/bind.h"
  12. #include "base/callback.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "dbus/dbus_export.h"
  15. #include "dbus/message.h"
  16. #include "dbus/object_proxy.h"
  17. // D-Bus objects frequently provide sets of properties accessed via a
  18. // standard interface of method calls and signals to obtain the current value,
  19. // set a new value and be notified of changes to the value. Unfortunately this
  20. // interface makes heavy use of variants and dictionaries of variants. The
  21. // classes defined here make dealing with properties in a type-safe manner
  22. // possible.
  23. //
  24. // Client implementation classes should define a Properties structure, deriving
  25. // from the PropertySet class defined here. This structure should contain a
  26. // member for each property defined as an instance of the Property<> class,
  27. // specifying the type to the template. Finally the structure should chain up
  28. // to the PropertySet constructor, and then call RegisterProperty() for each
  29. // property defined to associate them with their string name.
  30. //
  31. // Example:
  32. // class ExampleClient {
  33. // public:
  34. // struct Properties : public dbus::PropertySet {
  35. // dbus::Property<std::string> name;
  36. // dbus::Property<uint16_t> version;
  37. // dbus::Property<dbus::ObjectPath> parent;
  38. // dbus::Property<std::vector<std::string>> children;
  39. //
  40. // Properties(dbus::ObjectProxy* object_proxy,
  41. // const PropertyChangedCallback callback)
  42. // : dbus::PropertySet(object_proxy, "com.example.DBus", callback) {
  43. // RegisterProperty("Name", &name);
  44. // RegisterProperty("Version", &version);
  45. // RegisterProperty("Parent", &parent);
  46. // RegisterProperty("Children", &children);
  47. // }
  48. // virtual ~Properties() {}
  49. // };
  50. //
  51. // The Properties structure requires a pointer to the object proxy of the
  52. // actual object to track, and after construction should have signals
  53. // connected to that object and initial values set by calling ConnectSignals()
  54. // and GetAll(). The structure should not outlive the object proxy, so it
  55. // is recommended that the lifecycle of both be managed together.
  56. //
  57. // Example (continued):
  58. //
  59. // typedef std::map<std::pair<dbus::ObjectProxy*, Properties*>> Object;
  60. // typedef std::map<dbus::ObjectPath, Object> ObjectMap;
  61. // ObjectMap object_map_;
  62. //
  63. // dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path) {
  64. // return GetObject(object_path).first;
  65. // }
  66. //
  67. // Properties* GetProperties(const dbus::ObjectPath& object_path) {
  68. // return GetObject(object_path).second;
  69. // }
  70. //
  71. // Object GetObject(const dbus::ObjectPath& object_path) {
  72. // ObjectMap::iterator it = object_map_.find(object_path);
  73. // if (it != object_map_.end())
  74. // return it->second;
  75. //
  76. // dbus::ObjectProxy* object_proxy = bus->GetObjectProxy(...);
  77. // // connect signals, etc.
  78. //
  79. // Properties* properties = new Properties(
  80. // object_proxy,
  81. // base::BindRepeating(&PropertyChanged,
  82. // weak_ptr_factory_.GetWeakPtr(),
  83. // object_path));
  84. // properties->ConnectSignals();
  85. // properties->GetAll();
  86. //
  87. // Object object = std::make_pair(object_proxy, properties);
  88. // object_map_[object_path] = object;
  89. // return object;
  90. // }
  91. // };
  92. //
  93. // This now allows code using the client implementation to access properties
  94. // in a type-safe manner, and assuming the PropertyChanged callback is
  95. // propagated up to observers, be notified of changes. A typical access of
  96. // the current value of the name property would be:
  97. //
  98. // ExampleClient::Properties* p = example_client->GetProperties(object_path);
  99. // std::string name = p->name.value();
  100. //
  101. // Normally these values are updated from signals emitted by the remote object,
  102. // in case an explicit round-trip is needed to obtain the current value, the
  103. // Get() method can be used and indicates whether or not the value update was
  104. // successful. The updated value can be obtained in the callback using the
  105. // value() method.
  106. //
  107. // p->children.Get(base::BindOnce(&OnGetChildren));
  108. //
  109. // A new value can be set using the Set() method, the callback indicates
  110. // success only; it is up to the remote object when (and indeed if) it updates
  111. // the property value, and whether it emits a signal or a Get() call is
  112. // required to obtain it.
  113. //
  114. // p->version.Set(20, base::BindOnce(&OnSetVersion))
  115. namespace dbus {
  116. // D-Bus Properties interface constants, declared here rather than
  117. // in property.cc because template methods use them.
  118. const char kPropertiesInterface[] = "org.freedesktop.DBus.Properties";
  119. const char kPropertiesGetAll[] = "GetAll";
  120. const char kPropertiesGet[] = "Get";
  121. const char kPropertiesSet[] = "Set";
  122. const char kPropertiesChanged[] = "PropertiesChanged";
  123. class PropertySet;
  124. // PropertyBase is an abstract base-class consisting of the parts of
  125. // the Property<> template that are not type-specific, such as the
  126. // associated PropertySet, property name, and the type-unsafe parts
  127. // used by PropertySet.
  128. class CHROME_DBUS_EXPORT PropertyBase {
  129. public:
  130. PropertyBase();
  131. PropertyBase(const PropertyBase&) = delete;
  132. PropertyBase& operator=(const PropertyBase&) = delete;
  133. virtual ~PropertyBase();
  134. // Initializes the |property_set| and property |name| so that method
  135. // calls may be made from this class. This method is called by
  136. // PropertySet::RegisterProperty() passing |this| for |property_set| so
  137. // there should be no need to call it directly. If you do beware that
  138. // no ownership or reference to |property_set| is taken so that object
  139. // must outlive this one.
  140. void Init(PropertySet* property_set, const std::string& name);
  141. // Retrieves the name of this property, this may be useful in observers
  142. // to avoid specifying the name in more than once place, e.g.
  143. //
  144. // void Client::PropertyChanged(const dbus::ObjectPath& object_path,
  145. // const std::string &property_name) {
  146. // Properties& properties = GetProperties(object_path);
  147. // if (property_name == properties.version.name()) {
  148. // // Handle version property changing
  149. // }
  150. // }
  151. const std::string& name() const { return name_; }
  152. // Returns true if property is valid, false otherwise.
  153. bool is_valid() const { return is_valid_; }
  154. // Allows to mark Property as valid or invalid.
  155. void set_valid(bool is_valid) { is_valid_ = is_valid; }
  156. // Method used by PropertySet to retrieve the value from a MessageReader,
  157. // no knowledge of the contained type is required, this method returns
  158. // true if its expected type was found, false if not.
  159. // Implementation provided by specialization.
  160. virtual bool PopValueFromReader(MessageReader* reader) = 0;
  161. // Method used by PropertySet to append the set value to a MessageWriter,
  162. // no knowledge of the contained type is required.
  163. // Implementation provided by specialization.
  164. virtual void AppendSetValueToWriter(MessageWriter* writer) = 0;
  165. // Method used by test and stub implementations of dbus::PropertySet::Set
  166. // to replace the property value with the set value without using a
  167. // dbus::MessageReader.
  168. virtual void ReplaceValueWithSetValue() = 0;
  169. protected:
  170. // Retrieves the associated property set.
  171. PropertySet* property_set() { return property_set_; }
  172. private:
  173. // Pointer to the PropertySet instance that this instance is a member of,
  174. // no ownership is taken and |property_set_| must outlive this class.
  175. raw_ptr<PropertySet> property_set_;
  176. bool is_valid_;
  177. // Name of the property.
  178. std::string name_;
  179. };
  180. // PropertySet groups a collection of properties for a remote object
  181. // together into a single structure, fixing their types and name such
  182. // that calls made through it are type-safe.
  183. //
  184. // Clients always sub-class this to add the properties, and should always
  185. // provide a constructor that chains up to this and then calls
  186. // RegisterProperty() for each property defined.
  187. //
  188. // After creation, client code should call ConnectSignals() and most likely
  189. // GetAll() to seed initial values and update as changes occur.
  190. class CHROME_DBUS_EXPORT PropertySet {
  191. public:
  192. // Callback for changes to cached values of properties, either notified
  193. // via signal, or as a result of calls to Get() and GetAll(). The |name|
  194. // argument specifies the name of the property changed.
  195. using PropertyChangedCallback =
  196. base::RepeatingCallback<void(const std::string& name)>;
  197. // Constructs a property set, where |object_proxy| specifies the proxy for
  198. // the/ remote object that these properties are for, care should be taken to
  199. // ensure that this object does not outlive the lifetime of the proxy;
  200. // |interface| specifies the D-Bus interface of these properties, and
  201. // |property_changed_callback| specifies the callback for when properties
  202. // are changed, this may be a NULL callback.
  203. PropertySet(ObjectProxy* object_proxy, const std::string& interface,
  204. const PropertyChangedCallback& property_changed_callback);
  205. PropertySet(const PropertySet&) = delete;
  206. PropertySet& operator=(const PropertySet&) = delete;
  207. // Destructor; we don't hold on to any references or memory that needs
  208. // explicit clean-up, but clang thinks we might.
  209. virtual ~PropertySet();
  210. // Registers a property, generally called from the subclass constructor;
  211. // pass the |name| of the property as used in method calls and signals,
  212. // and the pointer to the |property| member of the structure. This will
  213. // call the PropertyBase::Init method.
  214. void RegisterProperty(const std::string& name, PropertyBase* property);
  215. // Connects property change notification signals to the object, generally
  216. // called immediately after the object is created and before calls to other
  217. // methods. Sub-classes may override to use different D-Bus signals.
  218. virtual void ConnectSignals();
  219. // Methods connected by ConnectSignals() and called by dbus:: when
  220. // a property is changed. Sub-classes may override if the property
  221. // changed signal provides different arguments.
  222. virtual void ChangedReceived(Signal* signal);
  223. virtual void ChangedConnected(const std::string& interface_name,
  224. const std::string& signal_name,
  225. bool success);
  226. // Callback for Get() method, |success| indicates whether or not the
  227. // value could be retrived, if true the new value can be obtained by
  228. // calling value() on the property.
  229. using GetCallback = base::OnceCallback<void(bool success)>;
  230. // Requests an updated value from the remote object for |property|
  231. // incurring a round-trip. |callback| will be called when the new
  232. // value is available. This may not be implemented by some interfaces,
  233. // and may be overriden by sub-classes if interfaces use different
  234. // method calls.
  235. virtual void Get(PropertyBase* property, GetCallback callback);
  236. virtual void OnGet(PropertyBase* property, GetCallback callback,
  237. Response* response);
  238. // The synchronous version of Get().
  239. // This should never be used on an interactive thread.
  240. virtual bool GetAndBlock(PropertyBase* property);
  241. // Queries the remote object for values of all properties and updates
  242. // initial values. Sub-classes may override to use a different D-Bus
  243. // method, or if the remote object does not support retrieving all
  244. // properties, either ignore or obtain each property value individually.
  245. virtual void GetAll();
  246. virtual void OnGetAll(Response* response);
  247. // Callback for Set() method, |success| indicates whether or not the
  248. // new property value was accepted by the remote object.
  249. using SetCallback = base::OnceCallback<void(bool success)>;
  250. // Requests that the remote object for |property| change the property to
  251. // its new value. |callback| will be called to indicate the success or
  252. // failure of the request, however the new value may not be available
  253. // depending on the remote object. This method may be overridden by
  254. // sub-classes if interfaces use different method calls.
  255. virtual void Set(PropertyBase* property, SetCallback callback);
  256. virtual void OnSet(PropertyBase* property, SetCallback callback,
  257. Response* response);
  258. // The synchronous version of Set().
  259. // This should never be used on an interactive thread.
  260. virtual bool SetAndBlock(PropertyBase* property);
  261. // Update properties by reading an array of dictionary entries, each
  262. // containing a string with the name and a variant with the value, from
  263. // |message_reader|. Returns false if message is in incorrect format.
  264. bool UpdatePropertiesFromReader(MessageReader* reader);
  265. // Updates a single property by reading a string with the name and a
  266. // variant with the value from |message_reader|. Returns false if message
  267. // is in incorrect format, or property type doesn't match.
  268. bool UpdatePropertyFromReader(MessageReader* reader);
  269. // Calls the property changed callback passed to the constructor, used
  270. // by sub-classes that do not call UpdatePropertiesFromReader() or
  271. // UpdatePropertyFromReader(). Takes the |name| of the changed property.
  272. void NotifyPropertyChanged(const std::string& name);
  273. // Retrieves the object proxy this property set was initialized with,
  274. // provided for sub-classes overriding methods that make D-Bus calls
  275. // and for Property<>. Not permitted with const references to this class.
  276. ObjectProxy* object_proxy() { return object_proxy_; }
  277. // Retrieves the interface of this property set.
  278. const std::string& interface() const { return interface_; }
  279. protected:
  280. // Get a weak pointer to this property set, provided so that sub-classes
  281. // overriding methods that make D-Bus calls may use the existing (or
  282. // override) callbacks without providing their own weak pointer factory.
  283. base::WeakPtr<PropertySet> GetWeakPtr() {
  284. return weak_ptr_factory_.GetWeakPtr();
  285. }
  286. private:
  287. // Invalidates properties by reading an array of names, from
  288. // |message_reader|. Returns false if message is in incorrect format.
  289. bool InvalidatePropertiesFromReader(MessageReader* reader);
  290. // Pointer to object proxy for making method calls, no ownership is taken
  291. // so this must outlive this class.
  292. raw_ptr<ObjectProxy> object_proxy_;
  293. // Interface of property, e.g. "org.chromium.ExampleService", this is
  294. // distinct from the interface of the method call itself which is the
  295. // general D-Bus Properties interface "org.freedesktop.DBus.Properties".
  296. std::string interface_;
  297. // Callback for property changes.
  298. PropertyChangedCallback property_changed_callback_;
  299. // Map of properties (as PropertyBase*) defined in the structure to
  300. // names as used in D-Bus method calls and signals. The base pointer
  301. // restricts property access via this map to type-unsafe and non-specific
  302. // actions only.
  303. typedef std::map<const std::string, PropertyBase*> PropertiesMap;
  304. PropertiesMap properties_map_;
  305. // Weak pointer factory as D-Bus callbacks may last longer than these
  306. // objects.
  307. base::WeakPtrFactory<PropertySet> weak_ptr_factory_{this};
  308. };
  309. // Property template, this defines the type-specific and type-safe methods
  310. // of properties that can be accessed as members of a PropertySet structure.
  311. //
  312. // Properties provide a cached value that has an initial sensible default
  313. // until the reply to PropertySet::GetAll() is retrieved and is updated by
  314. // all calls to that method, PropertySet::Get() and property changed signals
  315. // also handled by PropertySet. It can be obtained by calling value() on the
  316. // property.
  317. //
  318. // It is recommended that this cached value be used where necessary, with
  319. // code using PropertySet::PropertyChangedCallback to be notified of changes,
  320. // rather than incurring a round-trip to the remote object for each property
  321. // access.
  322. //
  323. // Where a round-trip is necessary, the Get() method is provided. And to
  324. // update the remote object value, the Set() method is also provided; these
  325. // both simply call methods on PropertySet.
  326. //
  327. // Handling of particular D-Bus types is performed via specialization,
  328. // typically the PopValueFromReader() and AppendSetValueToWriter() methods
  329. // will need to be provided, and in rare cases a constructor to provide a
  330. // default value. Specializations for basic D-Bus types, strings, object
  331. // paths and arrays are provided for you.
  332. template <class T>
  333. class CHROME_DBUS_EXPORT Property : public PropertyBase {
  334. public:
  335. Property() {}
  336. ~Property() override {}
  337. // Retrieves the cached value.
  338. const T& value() const { return value_; }
  339. // Requests an updated value from the remote object incurring a
  340. // round-trip. |callback| will be called when the new value is available.
  341. // This may not be implemented by some interfaces.
  342. virtual void Get(dbus::PropertySet::GetCallback callback) {
  343. property_set()->Get(this, std::move(callback));
  344. }
  345. // The synchronous version of Get().
  346. // This should never be used on an interactive thread.
  347. virtual bool GetAndBlock() {
  348. return property_set()->GetAndBlock(this);
  349. }
  350. // Requests that the remote object change the property value to |value|,
  351. // |callback| will be called to indicate the success or failure of the
  352. // request, however the new value may not be available depending on the
  353. // remote object.
  354. virtual void Set(const T& value, dbus::PropertySet::SetCallback callback) {
  355. set_value_ = value;
  356. property_set()->Set(this, std::move(callback));
  357. }
  358. // The synchronous version of Set().
  359. // This should never be used on an interactive thread.
  360. virtual bool SetAndBlock(const T& value) {
  361. set_value_ = value;
  362. return property_set()->SetAndBlock(this);
  363. }
  364. // Method used by PropertySet to retrieve the value from a MessageReader,
  365. // no knowledge of the contained type is required, this method returns
  366. // true if its expected type was found, false if not.
  367. bool PopValueFromReader(MessageReader* reader) override;
  368. // Method used by PropertySet to append the set value to a MessageWriter,
  369. // no knowledge of the contained type is required.
  370. // Implementation provided by specialization.
  371. void AppendSetValueToWriter(MessageWriter* writer) override;
  372. // Method used by test and stub implementations of dbus::PropertySet::Set
  373. // to replace the property value with the set value without using a
  374. // dbus::MessageReader.
  375. void ReplaceValueWithSetValue() override {
  376. value_ = set_value_;
  377. property_set()->NotifyPropertyChanged(name());
  378. }
  379. // Method used by test and stub implementations to directly set the
  380. // value of a property.
  381. void ReplaceValue(const T& value) {
  382. value_ = value;
  383. property_set()->NotifyPropertyChanged(name());
  384. }
  385. // Method used by test and stub implementations to directly set the
  386. // |set_value_| of a property.
  387. void ReplaceSetValueForTesting(const T& value) { set_value_ = value; }
  388. // Method used by test and stub implementations to retrieve the |set_value|
  389. // of a property.
  390. const T& GetSetValueForTesting() const { return set_value_; }
  391. private:
  392. // Current cached value of the property.
  393. T value_;
  394. // Replacement value of the property.
  395. T set_value_;
  396. };
  397. // Clang and GCC don't agree on how attributes should work for explicitly
  398. // instantiated templates. GCC ignores attributes on explicit instantiations
  399. // (and emits a warning) while Clang requires the visiblity attribute on the
  400. // explicit instantiations for them to be visible to other compilation units.
  401. // Hopefully clang and GCC agree one day, and this can be cleaned up:
  402. // https://llvm.org/bugs/show_bug.cgi?id=24815
  403. #pragma GCC diagnostic push
  404. #pragma GCC diagnostic ignored "-Wattributes"
  405. template <>
  406. CHROME_DBUS_EXPORT Property<uint8_t>::Property();
  407. template <>
  408. CHROME_DBUS_EXPORT bool Property<uint8_t>::PopValueFromReader(
  409. MessageReader* reader);
  410. template <>
  411. CHROME_DBUS_EXPORT void Property<uint8_t>::AppendSetValueToWriter(
  412. MessageWriter* writer);
  413. extern template class CHROME_DBUS_EXPORT Property<uint8_t>;
  414. template <>
  415. CHROME_DBUS_EXPORT Property<bool>::Property();
  416. template <>
  417. CHROME_DBUS_EXPORT bool Property<bool>::PopValueFromReader(
  418. MessageReader* reader);
  419. template <>
  420. CHROME_DBUS_EXPORT void Property<bool>::AppendSetValueToWriter(
  421. MessageWriter* writer);
  422. extern template class CHROME_DBUS_EXPORT Property<bool>;
  423. template <>
  424. CHROME_DBUS_EXPORT Property<int16_t>::Property();
  425. template <>
  426. CHROME_DBUS_EXPORT bool Property<int16_t>::PopValueFromReader(
  427. MessageReader* reader);
  428. template <>
  429. CHROME_DBUS_EXPORT void Property<int16_t>::AppendSetValueToWriter(
  430. MessageWriter* writer);
  431. extern template class CHROME_DBUS_EXPORT Property<int16_t>;
  432. template <>
  433. CHROME_DBUS_EXPORT Property<uint16_t>::Property();
  434. template <>
  435. CHROME_DBUS_EXPORT bool Property<uint16_t>::PopValueFromReader(
  436. MessageReader* reader);
  437. template <>
  438. CHROME_DBUS_EXPORT void Property<uint16_t>::AppendSetValueToWriter(
  439. MessageWriter* writer);
  440. extern template class CHROME_DBUS_EXPORT Property<uint16_t>;
  441. template <>
  442. CHROME_DBUS_EXPORT Property<int32_t>::Property();
  443. template <>
  444. CHROME_DBUS_EXPORT bool Property<int32_t>::PopValueFromReader(
  445. MessageReader* reader);
  446. template <>
  447. CHROME_DBUS_EXPORT void Property<int32_t>::AppendSetValueToWriter(
  448. MessageWriter* writer);
  449. extern template class CHROME_DBUS_EXPORT Property<int32_t>;
  450. template <>
  451. CHROME_DBUS_EXPORT Property<uint32_t>::Property();
  452. template <>
  453. CHROME_DBUS_EXPORT bool Property<uint32_t>::PopValueFromReader(
  454. MessageReader* reader);
  455. template <>
  456. CHROME_DBUS_EXPORT void Property<uint32_t>::AppendSetValueToWriter(
  457. MessageWriter* writer);
  458. extern template class CHROME_DBUS_EXPORT Property<uint32_t>;
  459. template <>
  460. CHROME_DBUS_EXPORT Property<int64_t>::Property();
  461. template <>
  462. CHROME_DBUS_EXPORT bool Property<int64_t>::PopValueFromReader(
  463. MessageReader* reader);
  464. template <>
  465. CHROME_DBUS_EXPORT void Property<int64_t>::AppendSetValueToWriter(
  466. MessageWriter* writer);
  467. extern template class CHROME_DBUS_EXPORT Property<int64_t>;
  468. template <>
  469. CHROME_DBUS_EXPORT Property<uint64_t>::Property();
  470. template <>
  471. CHROME_DBUS_EXPORT bool Property<uint64_t>::PopValueFromReader(
  472. MessageReader* reader);
  473. template <>
  474. CHROME_DBUS_EXPORT void Property<uint64_t>::AppendSetValueToWriter(
  475. MessageWriter* writer);
  476. extern template class CHROME_DBUS_EXPORT Property<uint64_t>;
  477. template <>
  478. CHROME_DBUS_EXPORT Property<double>::Property();
  479. template <>
  480. CHROME_DBUS_EXPORT bool Property<double>::PopValueFromReader(
  481. MessageReader* reader);
  482. template <>
  483. CHROME_DBUS_EXPORT void Property<double>::AppendSetValueToWriter(
  484. MessageWriter* writer);
  485. extern template class CHROME_DBUS_EXPORT Property<double>;
  486. template <>
  487. CHROME_DBUS_EXPORT bool Property<std::string>::PopValueFromReader(
  488. MessageReader* reader);
  489. template <>
  490. CHROME_DBUS_EXPORT void Property<std::string>::AppendSetValueToWriter(
  491. MessageWriter* writer);
  492. extern template class CHROME_DBUS_EXPORT Property<std::string>;
  493. template <>
  494. CHROME_DBUS_EXPORT bool Property<ObjectPath>::PopValueFromReader(
  495. MessageReader* reader);
  496. template <>
  497. CHROME_DBUS_EXPORT void Property<ObjectPath>::AppendSetValueToWriter(
  498. MessageWriter* writer);
  499. extern template class CHROME_DBUS_EXPORT Property<ObjectPath>;
  500. template <>
  501. CHROME_DBUS_EXPORT bool Property<std::vector<std::string>>::PopValueFromReader(
  502. MessageReader* reader);
  503. template <>
  504. CHROME_DBUS_EXPORT void Property<
  505. std::vector<std::string>>::AppendSetValueToWriter(MessageWriter* writer);
  506. extern template class CHROME_DBUS_EXPORT Property<std::vector<std::string>>;
  507. template <>
  508. CHROME_DBUS_EXPORT bool Property<std::vector<ObjectPath>>::PopValueFromReader(
  509. MessageReader* reader);
  510. template <>
  511. CHROME_DBUS_EXPORT void Property<
  512. std::vector<ObjectPath>>::AppendSetValueToWriter(MessageWriter* writer);
  513. extern template class CHROME_DBUS_EXPORT Property<std::vector<ObjectPath>>;
  514. template <>
  515. CHROME_DBUS_EXPORT bool Property<std::vector<uint8_t>>::PopValueFromReader(
  516. MessageReader* reader);
  517. template <>
  518. CHROME_DBUS_EXPORT void Property<std::vector<uint8_t>>::AppendSetValueToWriter(
  519. MessageWriter* writer);
  520. extern template class CHROME_DBUS_EXPORT Property<std::vector<uint8_t>>;
  521. template <>
  522. CHROME_DBUS_EXPORT bool
  523. Property<std::map<std::string, std::string>>::PopValueFromReader(
  524. MessageReader* reader);
  525. template <>
  526. CHROME_DBUS_EXPORT void
  527. Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
  528. MessageWriter* writer);
  529. extern template class CHROME_DBUS_EXPORT
  530. Property<std::map<std::string, std::string>>;
  531. template <>
  532. CHROME_DBUS_EXPORT bool
  533. Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
  534. PopValueFromReader(MessageReader* reader);
  535. template <>
  536. CHROME_DBUS_EXPORT void
  537. Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
  538. AppendSetValueToWriter(MessageWriter* writer);
  539. extern template class CHROME_DBUS_EXPORT
  540. Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
  541. template <>
  542. CHROME_DBUS_EXPORT bool
  543. Property<std::map<std::string, std::vector<uint8_t>>>::PopValueFromReader(
  544. MessageReader* reader);
  545. template <>
  546. CHROME_DBUS_EXPORT void
  547. Property<std::map<std::string, std::vector<uint8_t>>>::AppendSetValueToWriter(
  548. MessageWriter* writer);
  549. extern template class CHROME_DBUS_EXPORT
  550. Property<std::map<std::string, std::vector<uint8_t>>>;
  551. template <>
  552. CHROME_DBUS_EXPORT bool
  553. Property<std::map<uint16_t, std::vector<uint8_t>>>::PopValueFromReader(
  554. MessageReader* reader);
  555. template <>
  556. CHROME_DBUS_EXPORT void
  557. Property<std::map<uint16_t, std::vector<uint8_t>>>::AppendSetValueToWriter(
  558. MessageWriter* writer);
  559. extern template class CHROME_DBUS_EXPORT
  560. Property<std::map<uint16_t, std::vector<uint8_t>>>;
  561. #pragma GCC diagnostic pop
  562. } // namespace dbus
  563. #endif // DBUS_PROPERTY_H_