Refactor libupdater into a seperate module.

So that we can write native tests for updater functions. This CL adds a
testcase for getprop() function.

Test: mmma bootable/recovery; Run recovery_component_test on device.

Change-Id: Iff4c1ff63c5c71aded2f9686fed6b71cc298c228
diff --git a/tests/Android.mk b/tests/Android.mk
index 19cb809..ef822d1 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -41,25 +41,41 @@
 LOCAL_MODULE := recovery_component_test
 LOCAL_C_INCLUDES := bootable/recovery
 LOCAL_SRC_FILES := \
+    component/applypatch_test.cpp \
     component/edify_test.cpp \
-    component/verifier_test.cpp \
-    component/applypatch_test.cpp
+    component/updater_test.cpp \
+    component/verifier_test.cpp
 LOCAL_FORCE_STATIC_EXECUTABLE := true
+
+tune2fs_static_libraries := \
+    libext2_com_err \
+    libext2_blkid \
+    libext2_quota \
+    libext2_uuid_static \
+    libext2_e2p \
+    libext2fs
+
 LOCAL_STATIC_LIBRARIES := \
     libapplypatch \
     libedify \
     libotafault \
+    libupdater \
     libverifier \
-    libcrypto_utils \
-    libcrypto \
     libminui \
     libminzip \
+    libmounts \
+    liblog \
+    libselinux \
+    libext4_utils_static \
+    libsparse_static \
+    libcrypto_utils \
+    libcrypto \
     libcutils \
     libbz \
     libz \
-    libc \
     libbase \
-    liblog
+    libtune2fs \
+    $(tune2fs_static_libraries)
 
 testdata_out_path := $(TARGET_OUT_DATA_NATIVE_TESTS)/recovery
 testdata_files := $(call find-subdir-files, testdata/*)
diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp
new file mode 100644
index 0000000..ec9c290
--- /dev/null
+++ b/tests/component/updater_test.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include <android-base/properties.h>
+#include <gtest/gtest.h>
+
+#include "edify/expr.h"
+#include "error_code.h"
+#include "updater/install.h"
+
+struct selabel_handle *sehandle = nullptr;
+
+static void expect(const char* expected, const char* expr_str,
+                   ErrorCode error_code, CauseCode cause_code) {
+    Expr* e;
+    int error_count;
+    EXPECT_EQ(parse_string(expr_str, &e, &error_count), 0);
+
+    State state(expr_str, nullptr);
+
+    char* result = Evaluate(&state, e);
+
+    if (expected == nullptr) {
+        EXPECT_EQ(nullptr, result);
+    } else {
+        EXPECT_STREQ(expected, result);
+    }
+
+    EXPECT_EQ(error_code, state.error_code);
+    EXPECT_EQ(cause_code, state.cause_code);
+
+    free(result);
+}
+
+class UpdaterTest : public ::testing::Test {
+  protected:
+    virtual void SetUp() {
+        RegisterBuiltins();
+        RegisterInstallFunctions();
+        FinishRegistration();
+    }
+};
+
+TEST_F(UpdaterTest, getprop) {
+    expect(android::base::GetProperty("ro.product.device", "").c_str(),
+           "getprop(\"ro.product.device\")",
+           kNoError, kNoCause);
+
+    expect(android::base::GetProperty("ro.build.fingerprint", "").c_str(),
+           "getprop(\"ro.build.fingerprint\")",
+           kNoError, kNoCause);
+
+    // getprop() accepts only one parameter.
+    expect(nullptr, "getprop()", kNoError, kArgsParsingFailure);
+    expect(nullptr, "getprop(\"arg1\", \"arg2\")", kNoError, kArgsParsingFailure);
+}
diff --git a/updater/Android.mk b/updater/Android.mk
index d9fc72c..33e9738 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -14,41 +14,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# updater (static executable)
-# ===============================
-# Build a statically-linked binary to include in OTA packages.
-include $(CLEAR_VARS)
-
-updater_src_files := \
-    install.cpp \
-    blockimg.cpp \
-    updater.cpp
-
-LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(updater_src_files)
-
-LOCAL_STATIC_LIBRARIES += \
-    $(TARGET_RECOVERY_UPDATER_LIBS) \
-    $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
-    libfec \
-    libfec_rs \
-    libext4_utils_static \
-    libsquashfs_utils \
-    libcrypto_utils \
-    libcrypto \
-    libapplypatch \
-    libotafault \
-    libedify \
-    libminzip \
-    libmounts \
-    libz \
-    libbz \
-    libcutils \
-    liblog \
-    libselinux \
-    libbase \
-    liblog
-
 tune2fs_static_libraries := \
     libext2_com_err \
     libext2_blkid \
@@ -57,17 +22,77 @@
     libext2_e2p \
     libext2fs
 
-LOCAL_STATIC_LIBRARIES += \
+updater_common_static_libraries := \
+    libapplypatch \
+    libedify \
+    libminzip \
+    libmounts \
+    libotafault \
+    libext4_utils_static \
+    libfec \
+    libfec_rs \
+    liblog \
+    libselinux \
+    libsparse_static \
+    libsquashfs_utils \
+    libbz \
+    libz \
+    libbase \
+    libcrypto \
+    libcrypto_utils \
+    libcutils \
     libtune2fs \
     $(tune2fs_static_libraries)
 
-LOCAL_CFLAGS += -Wno-unused-parameter -Werror
-LOCAL_STATIC_LIBRARIES += \
-    libsparse_static \
-    libz
+# libupdater (static library)
+# ===============================
+include $(CLEAR_VARS)
 
-LOCAL_C_INCLUDES += external/e2fsprogs/misc
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
+LOCAL_MODULE := libupdater
+
+LOCAL_SRC_FILES := \
+    install.cpp \
+    blockimg.cpp
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/.. \
+    $(LOCAL_PATH)/include \
+    external/e2fsprogs/misc
+
+LOCAL_CFLAGS := \
+    -Wno-unused-parameter \
+    -Werror
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH)/include
+
+LOCAL_STATIC_LIBRARIES := \
+    $(updater_common_static_libraries)
+
+include $(BUILD_STATIC_LIBRARY)
+
+# updater (static executable)
+# ===============================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := updater
+
+LOCAL_SRC_FILES := \
+    updater.cpp
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/.. \
+    $(LOCAL_PATH)/include
+
+LOCAL_CFLAGS := \
+    -Wno-unused-parameter \
+    -Werror
+
+LOCAL_STATIC_LIBRARIES := \
+    libupdater \
+    $(TARGET_RECOVERY_UPDATER_LIBS) \
+    $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
+    $(updater_common_static_libraries)
 
 # Each library in TARGET_RECOVERY_UPDATER_LIBS should have a function
 # named "Register_<libname>()".  Here we emit a little C function that
@@ -108,8 +133,6 @@
 inc :=
 inc_dep_file :=
 
-LOCAL_MODULE := updater
-
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 
 include $(BUILD_EXECUTABLE)
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index 0caa1ac..433d980 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -45,12 +45,12 @@
 #include "applypatch/applypatch.h"
 #include "edify/expr.h"
 #include "error_code.h"
-#include "install.h"
+#include "updater/install.h"
 #include "openssl/sha.h"
 #include "minzip/Hash.h"
 #include "ota_io.h"
 #include "print_sha1.h"
-#include "updater.h"
+#include "updater/updater.h"
 
 #define BLOCKSIZE 4096
 
diff --git a/updater/blockimg.h b/updater/include/updater/blockimg.h
similarity index 100%
rename from updater/blockimg.h
rename to updater/include/updater/blockimg.h
diff --git a/updater/install.h b/updater/include/updater/install.h
similarity index 89%
rename from updater/install.h
rename to updater/include/updater/install.h
index b3b8a4d..8d6ca47 100644
--- a/updater/install.h
+++ b/updater/include/updater/install.h
@@ -17,11 +17,12 @@
 #ifndef _UPDATER_INSTALL_H_
 #define _UPDATER_INSTALL_H_
 
+struct State;
+
 void RegisterInstallFunctions();
 
 // uiPrintf function prints msg to screen as well as logs
-void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...) __attribute__((__format__(printf, 2, 3)));
-
-static int make_parents(char* _Nonnull name);
+void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...)
+    __attribute__((__format__(printf, 2, 3)));
 
 #endif
diff --git a/updater/updater.h b/updater/include/updater/updater.h
similarity index 100%
rename from updater/updater.h
rename to updater/include/updater/updater.h
diff --git a/updater/install.cpp b/updater/install.cpp
index 24e35cf..86cdd5d 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "updater/install.h"
+
 #include <ctype.h>
 #include <errno.h>
 #include <stdarg.h>
@@ -40,24 +42,22 @@
 #include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <android-base/stringprintf.h>
+#include <cutils/android_reboot.h>
 #include <ext4_utils/make_ext4fs.h>
 #include <ext4_utils/wipe.h>
 #include <selinux/label.h>
 #include <selinux/selinux.h>
 
-#include "bootloader.h"
 #include "applypatch/applypatch.h"
-#include "cutils/android_reboot.h"
-#include "cutils/misc.h"
+#include "bootloader.h"
 #include "edify/expr.h"
 #include "error_code.h"
 #include "minzip/DirUtil.h"
 #include "mounts.h"
 #include "openssl/sha.h"
 #include "ota_io.h"
-#include "updater.h"
-#include "install.h"
 #include "tune2fs.h"
+#include "updater/updater.h"
 
 // Send over the buffer to recovery though the command pipe.
 static void uiPrint(State* state, const std::string& buffer) {
@@ -90,6 +90,27 @@
     uiPrint(state, error_msg);
 }
 
+// Create all parent directories of name, if necessary.
+static int make_parents(char* name) {
+    char* p;
+    for (p = name + (strlen(name)-1); p > name; --p) {
+        if (*p != '/') continue;
+        *p = '\0';
+        if (make_parents(name) < 0) return -1;
+        int result = mkdir(name, 0700);
+        if (result == 0) printf("created [%s]\n", name);
+        *p = '/';
+        if (result == 0 || errno == EEXIST) {
+            // successfully created or already existed; we're done
+            return 0;
+        } else {
+            printf("failed to mkdir %s: %s\n", name, strerror(errno));
+            return -1;
+        }
+    }
+    return 0;
+}
+
 // Take a sha-1 digest and return it as a newly-allocated hex string.
 char* PrintSha1(const uint8_t* digest) {
     char* buffer = reinterpret_cast<char*>(malloc(SHA_DIGEST_LENGTH*2 + 1));
@@ -569,27 +590,6 @@
     }
 }
 
-// Create all parent directories of name, if necessary.
-static int make_parents(char* name) {
-    char* p;
-    for (p = name + (strlen(name)-1); p > name; --p) {
-        if (*p != '/') continue;
-        *p = '\0';
-        if (make_parents(name) < 0) return -1;
-        int result = mkdir(name, 0700);
-        if (result == 0) printf("created [%s]\n", name);
-        *p = '/';
-        if (result == 0 || errno == EEXIST) {
-            // successfully created or already existed; we're done
-            return 0;
-        } else {
-            printf("failed to mkdir %s: %s\n", name, strerror(errno));
-            return -1;
-        }
-    }
-    return 0;
-}
-
 // symlink target src1 src2 ...
 //    unlinks any previously existing src1, src2, etc before creating symlinks.
 Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
diff --git a/updater/updater.cpp b/updater/updater.cpp
index 74a4048..45e31e0 100644
--- a/updater/updater.cpp
+++ b/updater/updater.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "updater.h"
+#include "updater/updater.h"
 
 #include <stdio.h>
 #include <unistd.h>
@@ -27,10 +27,10 @@
 
 #include "config.h"
 #include "edify/expr.h"
-#include "blockimg.h"
-#include "install.h"
-#include "minzip/Zip.h"
 #include "minzip/SysUtil.h"
+#include "minzip/Zip.h"
+#include "updater/blockimg.h"
+#include "updater/install.h"
 
 // Generated by the makefile, this function defines the
 // RegisterDeviceExtensions() function, which calls all the