shill: Implement write-only properties
Certain properties (e.g. WIFI Passphrase) are write only and must
not be returned when Service.GetProperties() is called over D-Bus.
This CL implements WriteOnlyProperties, a write-only analog of the
read-only ConstProperties.
Also add a ReadablePropertyConstIterator which only returns the
readable properties. Switch over DBus adaptor and PropertyStore
to use that.
BUG=chromium-os:21196
TEST=Added 2 new unittests.
Change-Id: I52815cc395650e0b49e1acac8d4954deeebcee5d
Reviewed-on: https://gerrit.chromium.org/gerrit/11402
Commit-Ready: Gaurav Shah <gauravsh@chromium.org>
Reviewed-by: Gaurav Shah <gauravsh@chromium.org>
Tested-by: Gaurav Shah <gauravsh@chromium.org>
diff --git a/property_accessor.h b/property_accessor.h
index 542fd8d..306f9c8 100644
--- a/property_accessor.h
+++ b/property_accessor.h
@@ -7,6 +7,7 @@
#include <base/basictypes.h>
#include <base/logging.h>
+#include <gtest/gtest_prod.h> // for FRIEND_TEST.
#include "shill/accessor_interface.h"
#include "shill/error.h"
@@ -34,7 +35,7 @@
}
virtual ~PropertyAccessor() {}
- const T &Get() { return *property_; }
+ T Get(Error */*error*/) { return *property_; }
void Set(const T &value, Error */*error*/) {
*property_ = value;
}
@@ -52,7 +53,7 @@
}
virtual ~ConstPropertyAccessor() {}
- const T &Get() { return *property_; }
+ T Get(Error */*error*/) { return *property_; }
void Set(const T &/*value*/, Error *error) {
// TODO(quiche): check if this is the right error.
// (maybe Error::kPermissionDenied instead?)
@@ -64,6 +65,31 @@
DISALLOW_COPY_AND_ASSIGN(ConstPropertyAccessor);
};
+template <class T>
+class WriteOnlyPropertyAccessor : public AccessorInterface<T> {
+ public:
+ explicit WriteOnlyPropertyAccessor(T *property) : property_(property) {
+ DCHECK(property);
+ }
+ virtual ~WriteOnlyPropertyAccessor() {}
+
+ T Get(Error *error) {
+ error->Populate(Error::kPermissionDenied, "Property is write-only");
+ return T();
+ }
+ void Set(const T &value, Error */*error*/) {
+ *property_ = value;
+ }
+
+ private:
+ FRIEND_TEST(PropertyAccessorTest, SignedIntCorrectness);
+ FRIEND_TEST(PropertyAccessorTest, UnsignedIntCorrectness);
+ FRIEND_TEST(PropertyAccessorTest, StringCorrectness);
+
+ T * const property_;
+ DISALLOW_COPY_AND_ASSIGN(WriteOnlyPropertyAccessor);
+};
+
// CustomAccessor<> allows custom getter and setter methods to be provided.
// Thus, if the state to be returned is to be derived on-demand, we can
// still fit it into the AccessorInterface<> framework.
@@ -75,17 +101,23 @@
// attempts to set via the accessor.
// It is an error to pass NULL for either of the other two arguments.
CustomAccessor(C *target,
- T(C::*getter)(),
+ T(C::*getter)(Error *),
void(C::*setter)(const T&, Error *))
: target_(target),
getter_(getter),
setter_(setter) {
DCHECK(target);
- DCHECK(getter);
}
virtual ~CustomAccessor() {}
- const T &Get() { return storage_ = (target_->*getter_)(); }
+ T Get(Error *error) {
+ if (getter_)
+ return storage_ = (target_->*getter_)(error);
+
+ error->Populate(Error::kPermissionDenied, "Property is write-only");
+ return T();
+ }
+
void Set(const T &value, Error *error) {
if (setter_) {
(target_->*setter_)(value, error);
@@ -99,7 +131,7 @@
// Get() returns a const&, so we need to have internal storage to which to
// return a reference.
T storage_;
- T(C::*getter_)(void);
+ T(C::*getter_)(Error *);
void(C::*setter_)(const T&, Error *);
DISALLOW_COPY_AND_ASSIGN(CustomAccessor);
};