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_unittest.cc b/property_accessor_unittest.cc
index 4303d13..e65c576 100644
--- a/property_accessor_unittest.cc
+++ b/property_accessor_unittest.cc
@@ -28,29 +28,49 @@
   {
     Error error;
     Int32Accessor accessor(new PropertyAccessor<int32>(&int_store));
-    EXPECT_EQ(int_store, accessor->Get());
+    EXPECT_EQ(int_store, accessor->Get(&error));
 
     int32 expected_int32 = 127;
     accessor->Set(expected_int32, &error);
     ASSERT_TRUE(error.IsSuccess());
-    EXPECT_EQ(expected_int32, accessor->Get());
+    EXPECT_EQ(expected_int32, accessor->Get(&error));
 
     int_store = std::numeric_limits<int32>::max();
-    EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get());
+    EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get(&error));
   }
   {
     Error error;
     Int32Accessor accessor(new ConstPropertyAccessor<int32>(&int_store));
-    EXPECT_EQ(int_store, accessor->Get());
+    EXPECT_EQ(int_store, accessor->Get(&error));
 
     int32 expected_int32 = 127;
     accessor->Set(expected_int32, &error);
     ASSERT_FALSE(error.IsSuccess());
     EXPECT_EQ(Error::kInvalidArguments, error.type());
-    EXPECT_EQ(int_store, accessor->Get());
+    EXPECT_EQ(int_store, accessor->Get(&error));
 
     int_store = std::numeric_limits<int32>::max();
-    EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get());
+    EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get(&error));
+  }
+  {
+    Error error;
+    Int32Accessor accessor(new WriteOnlyPropertyAccessor<int32>(&int_store));
+    accessor->Get(&error);
+    ASSERT_TRUE(error.IsFailure());
+    EXPECT_EQ(Error::kPermissionDenied, error.type());
+  }
+  {
+    Error error;
+    int32 expected_int32 = 127;
+    WriteOnlyPropertyAccessor<int32> accessor(&expected_int32);
+    accessor.Set(expected_int32, &error);
+    ASSERT_TRUE(error.IsSuccess());
+    EXPECT_EQ(expected_int32, *accessor.property_);
+    EXPECT_EQ(int32(), accessor.Get(&error));
+    ASSERT_FALSE(error.IsSuccess());
+
+    expected_int32 = std::numeric_limits<int32>::max();
+    EXPECT_EQ(std::numeric_limits<int32>::max(), *accessor.property_);
   }
 }
 
@@ -59,29 +79,49 @@
   {
     Error error;
     Uint32Accessor accessor(new PropertyAccessor<uint32>(&int_store));
-    EXPECT_EQ(int_store, accessor->Get());
+    EXPECT_EQ(int_store, accessor->Get(&error));
 
     uint32 expected_uint32 = 127;
     accessor->Set(expected_uint32, &error);
     ASSERT_TRUE(error.IsSuccess());
-    EXPECT_EQ(expected_uint32, accessor->Get());
+    EXPECT_EQ(expected_uint32, accessor->Get(&error));
 
     int_store = std::numeric_limits<uint32>::max();
-    EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get());
+    EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get(&error));
   }
   {
     Error error;
     Uint32Accessor accessor(new ConstPropertyAccessor<uint32>(&int_store));
-    EXPECT_EQ(int_store, accessor->Get());
+    EXPECT_EQ(int_store, accessor->Get(&error));
 
     uint32 expected_uint32 = 127;
     accessor->Set(expected_uint32, &error);
     ASSERT_FALSE(error.IsSuccess());
     EXPECT_EQ(Error::kInvalidArguments, error.type());
-    EXPECT_EQ(int_store, accessor->Get());
+    EXPECT_EQ(int_store, accessor->Get(&error));
 
     int_store = std::numeric_limits<uint32>::max();
-    EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get());
+    EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get(&error));
+  }
+  {
+    Error error;
+    Uint32Accessor accessor(new WriteOnlyPropertyAccessor<uint32>(&int_store));
+    accessor->Get(&error);
+    ASSERT_TRUE(error.IsFailure());
+    EXPECT_EQ(Error::kPermissionDenied, error.type());
+  }
+  {
+    Error error;
+    uint32 expected_uint32 = 127;
+    WriteOnlyPropertyAccessor<uint32> accessor(&expected_uint32);
+    accessor.Set(expected_uint32, &error);
+    ASSERT_TRUE(error.IsSuccess());
+    EXPECT_EQ(expected_uint32, *accessor.property_);
+    EXPECT_EQ(uint32(), accessor.Get(&error));
+    ASSERT_FALSE(error.IsSuccess());
+
+    expected_uint32 = std::numeric_limits<uint32>::max();
+    EXPECT_EQ(std::numeric_limits<uint32>::max(), *accessor.property_);
   }
 }
 
@@ -90,29 +130,49 @@
   {
     Error error;
     StringAccessor accessor(new PropertyAccessor<string>(&storage));
-    EXPECT_EQ(storage, accessor->Get());
+    EXPECT_EQ(storage, accessor->Get(&error));
 
     string expected_string("what");
     accessor->Set(expected_string, &error);
     ASSERT_TRUE(error.IsSuccess());
-    EXPECT_EQ(expected_string, accessor->Get());
+    EXPECT_EQ(expected_string, accessor->Get(&error));
 
     storage = "nooooo";
-    EXPECT_EQ(storage, accessor->Get());
+    EXPECT_EQ(storage, accessor->Get(&error));
   }
   {
     Error error;
     StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
-    EXPECT_EQ(storage, accessor->Get());
+    EXPECT_EQ(storage, accessor->Get(&error));
 
     string expected_string("what");
     accessor->Set(expected_string, &error);
     ASSERT_FALSE(error.IsSuccess());
     EXPECT_EQ(Error::kInvalidArguments, error.type());
-    EXPECT_EQ(storage, accessor->Get());
+    EXPECT_EQ(storage, accessor->Get(&error));
 
     storage = "nooooo";
-    EXPECT_EQ(storage, accessor->Get());
+    EXPECT_EQ(storage, accessor->Get(&error));
+  }
+  {
+    Error error;
+    StringAccessor accessor(new WriteOnlyPropertyAccessor<string>(&storage));
+    accessor->Get(&error);
+    ASSERT_TRUE(error.IsFailure());
+    EXPECT_EQ(Error::kPermissionDenied, error.type());
+  }
+  {
+    Error error;
+    string expected_string = "what";
+    WriteOnlyPropertyAccessor<string> accessor(&expected_string);
+    accessor.Set(expected_string, &error);
+    ASSERT_TRUE(error.IsSuccess());
+    EXPECT_EQ(expected_string, *accessor.property_);
+    EXPECT_EQ(string(), accessor.Get(&error));
+    ASSERT_FALSE(error.IsSuccess());
+
+    expected_string = "nooooo";
+    EXPECT_EQ("nooooo", *accessor.property_);
   }
 }