updater: Let read_file() return Value::Type::STRING.

It used to return a Value blob to be consumed by sha1_check() (which has
been deprecated). Currently there's no other generic updater function
that works with BLOB Values. This CL changes read_file() to return a
string Value to make it more useful (e.g. allowing equality check).

Test: Run recovery_component_test and recovery_unit_test on marlin.
Change-Id: Iba986ba649030112babefe898f26aa9ffe69eeb7
diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp
index 91e5cc1..9fcf17f 100644
--- a/tests/component/updater_test.cpp
+++ b/tests/component/updater_test.cpp
@@ -51,6 +51,8 @@
 #include "updater/install.h"
 #include "updater/updater.h"
 
+using namespace std::string_literals;
+
 using PackageEntries = std::unordered_map<std::string, std::string>;
 
 static constexpr size_t kTransferListHeaderLines = 4;
@@ -366,6 +368,27 @@
   CloseArchive(handle);
 }
 
+TEST_F(UpdaterTest, read_file) {
+  // read_file() expects one argument.
+  expect(nullptr, "read_file()", kArgsParsingFailure);
+  expect(nullptr, "read_file(\"arg1\", \"arg2\")", kArgsParsingFailure);
+
+  // Write some value to file and read back.
+  TemporaryFile temp_file;
+  std::string script("write_value(\"foo\", \""s + temp_file.path + "\");");
+  expect("t", script, kNoCause);
+
+  script = "read_file(\""s + temp_file.path + "\") == \"foo\"";
+  expect("t", script, kNoCause);
+
+  script = "read_file(\""s + temp_file.path + "\") == \"bar\"";
+  expect("", script, kNoCause);
+
+  // It should fail gracefully when read fails.
+  script = "read_file(\"/doesntexist\")";
+  expect("", script, kNoCause);
+}
+
 TEST_F(UpdaterTest, write_value) {
   // write_value() expects two arguments.
   expect(nullptr, "write_value()", kArgsParsingFailure);
diff --git a/updater/install.cpp b/updater/install.cpp
index 02a6fe7..d0be955 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -742,7 +742,7 @@
 }
 
 // read_file(filename)
-//   Reads a local file 'filename' and returns its contents as a Value string.
+//   Reads a local file 'filename' and returns its contents as a string Value.
 Value* ReadFileFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
   if (argv.size() != 1) {
     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
@@ -754,13 +754,13 @@
   }
   const std::string& filename = args[0];
 
-  FileContents fc;
-  if (LoadFileContents(filename.c_str(), &fc) == 0) {
-    return new Value(Value::Type::BLOB, std::string(fc.data.cbegin(), fc.data.cend()));
+  std::string contents;
+  if (android::base::ReadFileToString(filename, &contents)) {
+    return new Value(Value::Type::STRING, std::move(contents));
   }
 
   // Leave it to caller to handle the failure.
-  LOG(ERROR) << name << ": Failed to read " << filename;
+  PLOG(ERROR) << name << ": Failed to read " << filename;
   return StringValue("");
 }