PolicyManager: Move the global variables to Provider members.

Per the Google C++ Style Guide, the global variables can't be
instances of a class and that includes smart pointers like
scoped_ptr. The alternative is to use plain pointers such as a
Variable<T>*. The disadvantage of this approach is that the memory
pointed by this global variable is managed by a singleton class
(a FooProvider) on production code and a different class during
testing (a FakeFooProvider). Also, these classes, fake and real
implementation, aren't forced to implement the same set of variables
since there's no common interface. Finally, the
construction/destruction of these variables also needs to handle the
global pointer, nulifying it after deletion.

This patch moves the global variable to a member of a base class that
hides the initialization of these variables to a subclass. This patch
includes a subclass with the real implementation.

BUG=chromium:338591
TEST=unittest passes.

Change-Id: I0aa43c51d72c65d97be280fd58307d085bb8577b
Reviewed-on: https://chromium-review.googlesource.com/184774
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/policy_manager/real_random_provider.cc b/policy_manager/real_random_provider.cc
new file mode 100644
index 0000000..28213fa
--- /dev/null
+++ b/policy_manager/real_random_provider.cc
@@ -0,0 +1,71 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <base/file_path.h>
+#include <base/file_util.h>
+#include <base/stringprintf.h>
+
+#include "policy_manager/real_random_provider.h"
+#include "policy_manager/variable.h"
+
+using std::string;
+
+namespace {
+
+// The device providing randomness.
+const char* kRandomDevice = "/dev/urandom";
+
+}  // namespace
+
+namespace chromeos_policy_manager {
+
+// A random seed variable.
+class RandomSeedVariable : public Variable<uint64_t> {
+ public:
+  RandomSeedVariable(const string& name, FILE* fp)
+      : Variable<uint64_t>(name), fp_(fp) {}
+  virtual ~RandomSeedVariable() {}
+
+ protected:
+  virtual const uint64_t* GetValue(base::TimeDelta /* timeout */,
+                                   string* errmsg) {
+    uint64_t result;
+    // Aliasing via char pointer abides by the C/C++ strict-aliasing rules.
+    char* const buf = reinterpret_cast<char*>(&result);
+    unsigned int buf_rd = 0;
+
+    while (buf_rd < sizeof(result)) {
+      int rd = fread(buf + buf_rd, 1, sizeof(result) - buf_rd, fp_.get());
+      if (rd == 0 || ferror(fp_.get())) {
+        // Either EOF on fp or read failed.
+        if (errmsg) {
+          *errmsg = StringPrintf("Error reading from the random device: %s",
+                                 kRandomDevice);
+        }
+        return NULL;
+      }
+      buf_rd += rd;
+    }
+
+    return new uint64_t(result);
+  }
+
+ private:
+  file_util::ScopedFILE fp_;
+
+  DISALLOW_COPY_AND_ASSIGN(RandomSeedVariable);
+};
+
+bool RealRandomProvider::DoInit(void) {
+  FILE* fp = fopen(kRandomDevice, "r");
+  if (!fp)
+    return false;
+  seed_.reset(new RandomSeedVariable("random_seed", fp));
+  return true;
+}
+
+}  // namespace chromeos_policy_manager