PM: Generic variable for copying the return value of a function call.

This is useful for quickly implementing variables that rely on calls to
utility functions/methods.

BUG=None
TEST=Unit tests.

Change-Id: I46040070c417b8c1f7b6081d4fe4d3b43a7a8101
Reviewed-on: https://chromium-review.googlesource.com/200659
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/policy_manager/generic_variables.h b/policy_manager/generic_variables.h
index 5309519..42e991d 100644
--- a/policy_manager/generic_variables.h
+++ b/policy_manager/generic_variables.h
@@ -9,6 +9,8 @@
 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_
 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_
 
+#include <base/callback.h>
+
 #include "update_engine/policy_manager/variable.h"
 
 namespace {
@@ -118,6 +120,37 @@
   const T obj_;
 };
 
+// Variable class returning a copy of a value returned by a given function. The
+// function is called every time the variable is being polled.
+template<typename T>
+class CallCopyVariable : public Variable<T> {
+ public:
+  CallCopyVariable(const std::string& name, base::Callback<T(void)> func)
+      : Variable<T>(name, kVariableModePoll), func_(func) {}
+  CallCopyVariable(const std::string& name,
+                   const base::TimeDelta poll_interval,
+                   base::Callback<T(void)> func)
+      : Variable<T>(name, poll_interval), func_(func) {}
+
+ protected:
+  // Variable override.
+  virtual const T* GetValue(base::TimeDelta /* timeout */,
+                            std::string* /* errmsg */) {
+    if (func_.is_null())
+      return nullptr;
+    return new T(func_.Run());
+  }
+
+ private:
+  FRIEND_TEST(PmCallCopyVariableTest, SimpleTest);
+
+  // The function to be called, stored as a base::Callback.
+  base::Callback<T(void)> func_;
+
+  DISALLOW_COPY_AND_ASSIGN(CallCopyVariable);
+};
+
+
 // A Variable class to implement simple Async variables. It provides two methods
 // SetValue and UnsetValue to modify the current value of the variable and
 // notify the registered observers whenever the value changed.