Merge "Add command line parser for simulator"
diff --git a/updater/include/updater/build_info.h b/updater/include/updater/build_info.h
index a1355e8..2229957 100644
--- a/updater/include/updater/build_info.h
+++ b/updater/include/updater/build_info.h
@@ -51,9 +51,18 @@
// Parses the given target-file, initializes the build properties and extracts the images.
bool ParseTargetFile(const std::string_view target_file_path, bool extracted_input);
+ std::string GetOemSettings() const {
+ return oem_settings_;
+ }
+ void SetOemSettings(const std::string_view oem_settings) {
+ oem_settings_ = oem_settings;
+ }
+
private:
// A map to store the system properties during simulation.
std::map<std::string, std::string, std::less<>> build_props_;
+ // A file that contains the oem properties.
+ std::string oem_settings_;
// A map from the blockdev_name to the FakeBlockDevice object, which contains the path to the
// temporary file.
std::map<std::string, FakeBlockDevice, std::less<>> blockdev_map_;
diff --git a/updater/simulator_runtime.cpp b/updater/simulator_runtime.cpp
index c8718c7..d2074d6 100644
--- a/updater/simulator_runtime.cpp
+++ b/updater/simulator_runtime.cpp
@@ -87,7 +87,11 @@
}
bool SimulatorRuntime::ReadFileToString(const std::string_view filename,
- std::string* /* content */) const {
+ std::string* content) const {
+ if (android::base::EndsWith(filename, "oem.prop")) {
+ return android::base::ReadFileToString(source_->GetOemSettings(), content);
+ }
+
LOG(INFO) << "SKip reading filename " << filename;
return true;
}
diff --git a/updater/update_simulator_main.cpp b/updater/update_simulator_main.cpp
index 019c404..278a440 100644
--- a/updater/update_simulator_main.cpp
+++ b/updater/update_simulator_main.cpp
@@ -14,11 +14,18 @@
* limitations under the License.
*/
+#include <getopt.h>
+#include <stdlib.h>
+#include <unistd.h>
+
#include <string>
+#include <string_view>
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include "edify/expr.h"
#include "otautil/error_code.h"
#include "otautil/paths.h"
#include "updater/blockimg.h"
@@ -28,21 +35,67 @@
#include "updater/simulator_runtime.h"
#include "updater/updater.h"
+using namespace std::string_literals;
+
+void Usage(std::string_view name) {
+ LOG(INFO) << "Usage: " << name << "[--oem_settings <oem_property_file>]"
+ << "[--skip_functions <skip_function_file>]"
+ << " --source <source_target_file>"
+ << " --ota_package <ota_package>";
+}
+
+Value* SimulatorPlaceHolderFn(const char* name, State* /* state */,
+ const std::vector<std::unique_ptr<Expr>>& /* argv */) {
+ LOG(INFO) << "Skip function " << name << " in host simulation";
+ return StringValue("t");
+}
+
int main(int argc, char** argv) {
// Write the logs to stdout.
android::base::InitLogging(argv, &android::base::StderrLogger);
- if (argc != 3 && argc != 4) {
- LOG(ERROR) << "unexpected number of arguments: " << argc << std::endl
- << "Usage: " << argv[0] << " <source_target-file> <ota_package>";
- return EXIT_FAILURE;
+ std::string oem_settings;
+ std::string skip_function_file;
+ std::string source_target_file;
+ std::string package_name;
+
+ constexpr struct option OPTIONS[] = {
+ { "oem_settings", required_argument, nullptr, 0 },
+ { "ota_package", required_argument, nullptr, 0 },
+ { "skip_functions", required_argument, nullptr, 0 },
+ { "source", required_argument, nullptr, 0 },
+ { nullptr, 0, nullptr, 0 },
+ };
+
+ int arg;
+ int option_index;
+ while ((arg = getopt_long(argc, argv, "", OPTIONS, &option_index)) != -1) {
+ if (arg != 0) {
+ LOG(ERROR) << "Invalid command argument";
+ Usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+ auto option_name = OPTIONS[option_index].name;
+ // The same oem property file used during OTA generation. It's needed for file_getprop() to
+ // return the correct value for the source build.
+ if (option_name == "oem_settings"s) {
+ oem_settings = optarg;
+ } else if (option_name == "skip_functions"s) {
+ skip_function_file = optarg;
+ } else if (option_name == "source"s) {
+ source_target_file = optarg;
+ } else if (option_name == "ota_package"s) {
+ package_name = optarg;
+ } else {
+ Usage(argv[0]);
+ return EXIT_FAILURE;
+ }
}
- // TODO(xunchang) implement a commandline parser, e.g. it can take an oem property so that the
- // file_getprop() will return correct value.
-
- std::string source_target_file = argv[1];
- std::string package_name = argv[2];
+ if (source_target_file.empty() || package_name.empty()) {
+ Usage(argv[0]);
+ return EXIT_FAILURE;
+ }
// Configure edify's functions.
RegisterBuiltins();
@@ -50,6 +103,22 @@
RegisterBlockImageFunctions();
RegisterDynamicPartitionsFunctions();
+ if (!skip_function_file.empty()) {
+ std::string content;
+ if (!android::base::ReadFileToString(skip_function_file, &content)) {
+ PLOG(ERROR) << "Failed to read " << skip_function_file;
+ return EXIT_FAILURE;
+ }
+
+ auto lines = android::base::Split(content, "\n");
+ for (const auto& line : lines) {
+ if (line.empty() || android::base::StartsWith(line, "#")) {
+ continue;
+ }
+ RegisterFunction(line, SimulatorPlaceHolderFn);
+ }
+ }
+
TemporaryFile temp_saved_source;
TemporaryFile temp_last_command;
TemporaryDir temp_stash_base;
@@ -67,6 +136,11 @@
return EXIT_FAILURE;
}
+ if (!oem_settings.empty()) {
+ CHECK_EQ(0, access(oem_settings.c_str(), R_OK));
+ source_build_info.SetOemSettings(oem_settings);
+ }
+
Updater updater(std::make_unique<SimulatorRuntime>(&source_build_info));
if (!updater.Init(cmd_pipe.release(), package_name, false)) {
return EXIT_FAILURE;