PolicyManager: Add an Observer interface to notify value changes.

This patch uses the Observer design pattern to expose the value
changed event on kVariableModeAsync variables. This will be consumed
by the EvaluationContext whenever it needs to wait for a value change
to re-evaluate the policy.

BUG=chromium:341209
TEST=Unit tests added and passing.

Change-Id: I7b3939751d49270650252c0fb0dbcc1f6ec92930
Reviewed-on: https://chromium-review.googlesource.com/187900
Reviewed-by: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/policy_manager/variable_unittest.cc b/policy_manager/variable_unittest.cc
index 5d3b8d9..2a6824a 100644
--- a/policy_manager/variable_unittest.cc
+++ b/policy_manager/variable_unittest.cc
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <vector>
+
 #include <gtest/gtest.h>
 
 #include "update_engine/policy_manager/variable.h"
 
 using base::TimeDelta;
 using std::string;
+using std::vector;
 
 namespace chromeos_policy_manager {
 
@@ -56,4 +59,47 @@
   EXPECT_EQ(var.GetPollInterval(), TimeDelta::FromMinutes(3));
 }
 
+class BaseVariableObserver : public BaseVariable::Observer {
+ public:
+  void ValueChanged(BaseVariable* variable) {
+    calls_.push_back(variable);
+  }
+
+  // List of called functions.
+  vector<BaseVariable*> calls_;
+};
+
+TEST(PmBaseVariableTest, RepeatedObserverTest) {
+  DefaultVariable<int> var("var", kVariableModeAsync);
+  BaseVariableObserver observer;
+  var.AddObserver(&observer);
+  EXPECT_EQ(var.observer_list_.size(), 1);
+  var.AddObserver(&observer);
+  EXPECT_EQ(var.observer_list_.size(), 1);
+  var.RemoveObserver(&observer);
+  EXPECT_EQ(var.observer_list_.size(), 0);
+  var.RemoveObserver(&observer);
+  EXPECT_EQ(var.observer_list_.size(), 0);
+}
+
+TEST(PmBaseVariableTest, NotifyValueChangedTest) {
+  DefaultVariable<int> var("var", kVariableModeAsync);
+  BaseVariableObserver observer1;
+  var.AddObserver(&observer1);
+  // Simulate a value change on the variable's implementation.
+  var.NotifyValueChanged();
+
+  ASSERT_EQ(observer1.calls_.size(), 1);
+  // Check that the observer is called with the right argument.
+  EXPECT_EQ(observer1.calls_[0], &var);
+
+  BaseVariableObserver observer2;
+  var.AddObserver(&observer2);
+  var.NotifyValueChanged();
+
+  // Check that all the observers are called.
+  EXPECT_EQ(observer1.calls_.size(), 2);
+  EXPECT_EQ(observer2.calls_.size(), 1);
+}
+
 }  // namespace chromeos_policy_manager