Refactor derive_sdk to be more testable

Refactor the code into a reusable library that is used from the
derive_sdk binary as well as a newly added cc_test.

The code now accepts an argument for which dir to scan for mounted
modules.

Add a simple test for the current system image R SDK version for now.

Bug: 173188089
Test: atest derive_sdk_test
Change-Id: If7442d515d55b35174d396cc579ee2c9865da2b5
diff --git a/derive_sdk/derive_sdk.cpp b/derive_sdk/derive_sdk.cpp
index 1b85c90..fb5f1f5 100644
--- a/derive_sdk/derive_sdk.cpp
+++ b/derive_sdk/derive_sdk.cpp
@@ -16,6 +16,8 @@
 
 #define LOG_TAG "derive_sdk"
 
+#include "derive_sdk.h"
+
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
@@ -31,11 +33,15 @@
 
 using com::android::sdkext::proto::SdkVersion;
 
-int main(int, char**) {
-  std::unique_ptr<DIR, decltype(&closedir)> apex(opendir("/apex"), closedir);
+namespace android {
+namespace derivesdk {
+
+bool SetSdkLevels(const std::string& mountpath) {
+  std::unique_ptr<DIR, decltype(&closedir)> apex(opendir(mountpath.c_str()),
+                                                 closedir);
   if (!apex) {
-    LOG(ERROR) << "Could not read /apex";
-    return EXIT_FAILURE;
+    LOG(ERROR) << "Could not read " + mountpath;
+    return false;
   }
   struct dirent* de;
   std::vector<std::string> paths;
@@ -45,7 +51,7 @@
       // Skip <name>@<ver> dirs, as they are bind-mounted to <name>
       continue;
     }
-    std::string path = "/apex/" + name + "/etc/sdkinfo.binarypb";
+    std::string path = mountpath + "/" + name + "/etc/sdkinfo.binarypb";
     struct stat statbuf;
     if (stat(path.c_str(), &statbuf) == 0) {
       paths.push_back(path);
@@ -72,15 +78,18 @@
 
   if (!android::base::SetProperty("build.version.extensions.r", prop_value)) {
     LOG(ERROR) << "failed to set r sdk_info prop";
-    return EXIT_FAILURE;
+    return false;
   }
   if (android::modules::sdklevel::IsAtLeastS()) {
     if (!android::base::SetProperty("build.version.extensions.s", prop_value)) {
       LOG(ERROR) << "failed to set s sdk_info prop";
-      return EXIT_FAILURE;
+      return false;
     }
   }
 
   LOG(INFO) << "Extension version is " << prop_value;
-  return EXIT_SUCCESS;
+  return true;
 }
+
+}  // namespace derivesdk
+}  // namespace android