188e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko// Copyright 2014 The Chromium OS Authors. All rights reserved.
288e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko// Use of this source code is governed by a BSD-style license that can be
388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko// found in the LICENSE file.
488e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
5fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#ifndef LIBBRILLO_BRILLO_DBUS_DBUS_PROPERTY_H_
6fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#define LIBBRILLO_BRILLO_DBUS_DBUS_PROPERTY_H_
788e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
89ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/dbus/data_serialization.h>
988e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko#include <dbus/property.h>
1088e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
119ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo {
1288e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenkonamespace dbus_utils {
1388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
1488e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko// Re-implementation of dbus::Property<T> that can handle any type supported by
1588e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko// D-Bus data serialization layer, such as vectors, maps, tuples, etc.
1688e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko// This class is pretty much a copy of dbus::Property<T> from dbus/property.h
1788e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko// except that it provides the implementations for PopValueFromReader and
1888e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko// AppendSetValueToWriter.
1905d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenkotemplate<class T>
2088e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenkoclass Property : public dbus::PropertyBase {
2188e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko public:
2288e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  Property() = default;
2388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
2488e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Retrieves the cached value.
2588e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  const T& value() const { return value_; }
2688e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
2788e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Requests an updated value from the remote object incurring a
2888e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // round-trip. |callback| will be called when the new value is available.
2988e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // This may not be implemented by some interfaces.
3088e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  void Get(dbus::PropertySet::GetCallback callback) {
3188e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    property_set()->Get(this, callback);
3288e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  }
3388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
34f9994ed608b9c3a732c9ecb1c3a3b6f6c9c2b584Ningyuan Wang  // Synchronous vesion of Get().
35f9994ed608b9c3a732c9ecb1c3a3b6f6c9c2b584Ningyuan Wang  bool GetAndBlock() {
36f9994ed608b9c3a732c9ecb1c3a3b6f6c9c2b584Ningyuan Wang    return property_set()->GetAndBlock(this);
37f9994ed608b9c3a732c9ecb1c3a3b6f6c9c2b584Ningyuan Wang  }
38f9994ed608b9c3a732c9ecb1c3a3b6f6c9c2b584Ningyuan Wang
3988e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Requests that the remote object change the property value to |value|,
4088e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // |callback| will be called to indicate the success or failure of the
4188e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // request, however the new value may not be available depending on the
4288e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // remote object.
4388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  void Set(const T& value, dbus::PropertySet::SetCallback callback) {
4488e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    set_value_ = value;
4588e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    property_set()->Set(this, callback);
4688e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  }
4788e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
48ceda6cb7f3944c1bf10c73ab6252b940bcca996fNingyuan Wang  // Synchronous version of Set().
49ceda6cb7f3944c1bf10c73ab6252b940bcca996fNingyuan Wang  bool SetAndBlock(const T& value) {
50ceda6cb7f3944c1bf10c73ab6252b940bcca996fNingyuan Wang    set_value_ = value;
51ceda6cb7f3944c1bf10c73ab6252b940bcca996fNingyuan Wang    return property_set()->SetAndBlock(this);
52ceda6cb7f3944c1bf10c73ab6252b940bcca996fNingyuan Wang  }
53ceda6cb7f3944c1bf10c73ab6252b940bcca996fNingyuan Wang
5488e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Method used by PropertySet to retrieve the value from a MessageReader,
5588e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // no knowledge of the contained type is required, this method returns
5688e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // true if its expected type was found, false if not.
5788e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  bool PopValueFromReader(dbus::MessageReader* reader) override {
5888e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    return PopVariantValueFromReader(reader, &value_);
5988e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  }
6088e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
6188e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Method used by PropertySet to append the set value to a MessageWriter,
6288e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // no knowledge of the contained type is required.
6388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Implementation provided by specialization.
6488e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  void AppendSetValueToWriter(dbus::MessageWriter* writer) override {
6588e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    AppendValueToWriterAsVariant(writer, set_value_);
6688e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  }
6788e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
6888e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Method used by test and stub implementations of dbus::PropertySet::Set
6988e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // to replace the property value with the set value without using a
7088e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // dbus::MessageReader.
7188e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  void ReplaceValueWithSetValue() override {
7288e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    value_ = set_value_;
7388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    property_set()->NotifyPropertyChanged(name());
7488e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  }
7588e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
7688e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Method used by test and stub implementations to directly set the
7788e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // value of a property.
7888e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  void ReplaceValue(const T& value) {
7988e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    value_ = value;
8088e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko    property_set()->NotifyPropertyChanged(name());
8188e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  }
8288e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
8388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko private:
8488e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Current cached value of the property.
8588e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  T value_;
8688e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
8788e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  // Replacement value of the property.
8888e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko  T set_value_;
8988e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko};
9088e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
9188e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko}  // namespace dbus_utils
929ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko}  // namespace brillo
9388e2235d5f6385612248ae76cc314b9975c28bf8Alex Vakulenko
94fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#endif  // LIBBRILLO_BRILLO_DBUS_DBUS_PROPERTY_H_
95