1*acea8879SAndroid Build Coastguard Worker /*
2*acea8879SAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*acea8879SAndroid Build Coastguard Worker *
4*acea8879SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*acea8879SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*acea8879SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*acea8879SAndroid Build Coastguard Worker *
8*acea8879SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*acea8879SAndroid Build Coastguard Worker *
10*acea8879SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*acea8879SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*acea8879SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*acea8879SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*acea8879SAndroid Build Coastguard Worker * limitations under the License.
15*acea8879SAndroid Build Coastguard Worker */
16*acea8879SAndroid Build Coastguard Worker
17*acea8879SAndroid Build Coastguard Worker #include <getopt.h>
18*acea8879SAndroid Build Coastguard Worker #include <stdlib.h>
19*acea8879SAndroid Build Coastguard Worker #include <unistd.h>
20*acea8879SAndroid Build Coastguard Worker
21*acea8879SAndroid Build Coastguard Worker #include <string>
22*acea8879SAndroid Build Coastguard Worker #include <string_view>
23*acea8879SAndroid Build Coastguard Worker
24*acea8879SAndroid Build Coastguard Worker #include <android-base/file.h>
25*acea8879SAndroid Build Coastguard Worker #include <android-base/logging.h>
26*acea8879SAndroid Build Coastguard Worker #include <android-base/strings.h>
27*acea8879SAndroid Build Coastguard Worker
28*acea8879SAndroid Build Coastguard Worker #include "edify/expr.h"
29*acea8879SAndroid Build Coastguard Worker #include "otautil/error_code.h"
30*acea8879SAndroid Build Coastguard Worker #include "otautil/paths.h"
31*acea8879SAndroid Build Coastguard Worker #include "updater/blockimg.h"
32*acea8879SAndroid Build Coastguard Worker #include "updater/build_info.h"
33*acea8879SAndroid Build Coastguard Worker #include "updater/dynamic_partitions.h"
34*acea8879SAndroid Build Coastguard Worker #include "updater/install.h"
35*acea8879SAndroid Build Coastguard Worker #include "updater/simulator_runtime.h"
36*acea8879SAndroid Build Coastguard Worker #include "updater/updater.h"
37*acea8879SAndroid Build Coastguard Worker
38*acea8879SAndroid Build Coastguard Worker using namespace std::string_literals;
39*acea8879SAndroid Build Coastguard Worker
Usage(std::string_view name)40*acea8879SAndroid Build Coastguard Worker void Usage(std::string_view name) {
41*acea8879SAndroid Build Coastguard Worker LOG(INFO) << "Usage: " << name << "[--oem_settings <oem_property_file>]"
42*acea8879SAndroid Build Coastguard Worker << "[--skip_functions <skip_function_file>]"
43*acea8879SAndroid Build Coastguard Worker << " --source <source_target_file>"
44*acea8879SAndroid Build Coastguard Worker << " --ota_package <ota_package>";
45*acea8879SAndroid Build Coastguard Worker }
46*acea8879SAndroid Build Coastguard Worker
SimulatorPlaceHolderFn(const char * name,State *,const std::vector<std::unique_ptr<Expr>> &)47*acea8879SAndroid Build Coastguard Worker Value* SimulatorPlaceHolderFn(const char* name, State* /* state */,
48*acea8879SAndroid Build Coastguard Worker const std::vector<std::unique_ptr<Expr>>& /* argv */) {
49*acea8879SAndroid Build Coastguard Worker LOG(INFO) << "Skip function " << name << " in host simulation";
50*acea8879SAndroid Build Coastguard Worker return StringValue("t");
51*acea8879SAndroid Build Coastguard Worker }
52*acea8879SAndroid Build Coastguard Worker
main(int argc,char ** argv)53*acea8879SAndroid Build Coastguard Worker int main(int argc, char** argv) {
54*acea8879SAndroid Build Coastguard Worker // Write the logs to stdout.
55*acea8879SAndroid Build Coastguard Worker android::base::InitLogging(argv, &android::base::StderrLogger);
56*acea8879SAndroid Build Coastguard Worker
57*acea8879SAndroid Build Coastguard Worker std::string oem_settings;
58*acea8879SAndroid Build Coastguard Worker std::string skip_function_file;
59*acea8879SAndroid Build Coastguard Worker std::string source_target_file;
60*acea8879SAndroid Build Coastguard Worker std::string package_name;
61*acea8879SAndroid Build Coastguard Worker std::string work_dir;
62*acea8879SAndroid Build Coastguard Worker bool keep_images = false;
63*acea8879SAndroid Build Coastguard Worker
64*acea8879SAndroid Build Coastguard Worker constexpr struct option OPTIONS[] = {
65*acea8879SAndroid Build Coastguard Worker { "keep_images", no_argument, nullptr, 0 },
66*acea8879SAndroid Build Coastguard Worker { "oem_settings", required_argument, nullptr, 0 },
67*acea8879SAndroid Build Coastguard Worker { "ota_package", required_argument, nullptr, 0 },
68*acea8879SAndroid Build Coastguard Worker { "skip_functions", required_argument, nullptr, 0 },
69*acea8879SAndroid Build Coastguard Worker { "source", required_argument, nullptr, 0 },
70*acea8879SAndroid Build Coastguard Worker { "work_dir", required_argument, nullptr, 0 },
71*acea8879SAndroid Build Coastguard Worker { nullptr, 0, nullptr, 0 },
72*acea8879SAndroid Build Coastguard Worker };
73*acea8879SAndroid Build Coastguard Worker
74*acea8879SAndroid Build Coastguard Worker int arg;
75*acea8879SAndroid Build Coastguard Worker int option_index;
76*acea8879SAndroid Build Coastguard Worker while ((arg = getopt_long(argc, argv, "", OPTIONS, &option_index)) != -1) {
77*acea8879SAndroid Build Coastguard Worker if (arg != 0) {
78*acea8879SAndroid Build Coastguard Worker LOG(ERROR) << "Invalid command argument";
79*acea8879SAndroid Build Coastguard Worker Usage(argv[0]);
80*acea8879SAndroid Build Coastguard Worker return EXIT_FAILURE;
81*acea8879SAndroid Build Coastguard Worker }
82*acea8879SAndroid Build Coastguard Worker auto option_name = OPTIONS[option_index].name;
83*acea8879SAndroid Build Coastguard Worker // The same oem property file used during OTA generation. It's needed for file_getprop() to
84*acea8879SAndroid Build Coastguard Worker // return the correct value for the source build.
85*acea8879SAndroid Build Coastguard Worker if (option_name == "oem_settings"s) {
86*acea8879SAndroid Build Coastguard Worker oem_settings = optarg;
87*acea8879SAndroid Build Coastguard Worker } else if (option_name == "skip_functions"s) {
88*acea8879SAndroid Build Coastguard Worker skip_function_file = optarg;
89*acea8879SAndroid Build Coastguard Worker } else if (option_name == "source"s) {
90*acea8879SAndroid Build Coastguard Worker source_target_file = optarg;
91*acea8879SAndroid Build Coastguard Worker } else if (option_name == "ota_package"s) {
92*acea8879SAndroid Build Coastguard Worker package_name = optarg;
93*acea8879SAndroid Build Coastguard Worker } else if (option_name == "keep_images"s) {
94*acea8879SAndroid Build Coastguard Worker keep_images = true;
95*acea8879SAndroid Build Coastguard Worker } else if (option_name == "work_dir"s) {
96*acea8879SAndroid Build Coastguard Worker work_dir = optarg;
97*acea8879SAndroid Build Coastguard Worker } else {
98*acea8879SAndroid Build Coastguard Worker Usage(argv[0]);
99*acea8879SAndroid Build Coastguard Worker return EXIT_FAILURE;
100*acea8879SAndroid Build Coastguard Worker }
101*acea8879SAndroid Build Coastguard Worker }
102*acea8879SAndroid Build Coastguard Worker
103*acea8879SAndroid Build Coastguard Worker if (source_target_file.empty() || package_name.empty()) {
104*acea8879SAndroid Build Coastguard Worker Usage(argv[0]);
105*acea8879SAndroid Build Coastguard Worker return EXIT_FAILURE;
106*acea8879SAndroid Build Coastguard Worker }
107*acea8879SAndroid Build Coastguard Worker
108*acea8879SAndroid Build Coastguard Worker // Configure edify's functions.
109*acea8879SAndroid Build Coastguard Worker RegisterBuiltins();
110*acea8879SAndroid Build Coastguard Worker RegisterInstallFunctions();
111*acea8879SAndroid Build Coastguard Worker RegisterBlockImageFunctions();
112*acea8879SAndroid Build Coastguard Worker RegisterDynamicPartitionsFunctions();
113*acea8879SAndroid Build Coastguard Worker
114*acea8879SAndroid Build Coastguard Worker if (!skip_function_file.empty()) {
115*acea8879SAndroid Build Coastguard Worker std::string content;
116*acea8879SAndroid Build Coastguard Worker if (!android::base::ReadFileToString(skip_function_file, &content)) {
117*acea8879SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to read " << skip_function_file;
118*acea8879SAndroid Build Coastguard Worker return EXIT_FAILURE;
119*acea8879SAndroid Build Coastguard Worker }
120*acea8879SAndroid Build Coastguard Worker
121*acea8879SAndroid Build Coastguard Worker auto lines = android::base::Split(content, "\n");
122*acea8879SAndroid Build Coastguard Worker for (const auto& line : lines) {
123*acea8879SAndroid Build Coastguard Worker if (line.empty() || android::base::StartsWith(line, "#")) {
124*acea8879SAndroid Build Coastguard Worker continue;
125*acea8879SAndroid Build Coastguard Worker }
126*acea8879SAndroid Build Coastguard Worker RegisterFunction(line, SimulatorPlaceHolderFn);
127*acea8879SAndroid Build Coastguard Worker }
128*acea8879SAndroid Build Coastguard Worker }
129*acea8879SAndroid Build Coastguard Worker
130*acea8879SAndroid Build Coastguard Worker TemporaryFile temp_saved_source;
131*acea8879SAndroid Build Coastguard Worker TemporaryFile temp_last_command;
132*acea8879SAndroid Build Coastguard Worker TemporaryDir temp_stash_base;
133*acea8879SAndroid Build Coastguard Worker
134*acea8879SAndroid Build Coastguard Worker Paths::Get().set_cache_temp_source(temp_saved_source.path);
135*acea8879SAndroid Build Coastguard Worker Paths::Get().set_last_command_file(temp_last_command.path);
136*acea8879SAndroid Build Coastguard Worker Paths::Get().set_stash_directory_base(temp_stash_base.path);
137*acea8879SAndroid Build Coastguard Worker
138*acea8879SAndroid Build Coastguard Worker TemporaryFile cmd_pipe;
139*acea8879SAndroid Build Coastguard Worker TemporaryDir source_temp_dir;
140*acea8879SAndroid Build Coastguard Worker if (work_dir.empty()) {
141*acea8879SAndroid Build Coastguard Worker work_dir = source_temp_dir.path;
142*acea8879SAndroid Build Coastguard Worker }
143*acea8879SAndroid Build Coastguard Worker
144*acea8879SAndroid Build Coastguard Worker BuildInfo source_build_info(work_dir, keep_images);
145*acea8879SAndroid Build Coastguard Worker if (!source_build_info.ParseTargetFile(source_target_file, false)) {
146*acea8879SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to parse the target file " << source_target_file;
147*acea8879SAndroid Build Coastguard Worker return EXIT_FAILURE;
148*acea8879SAndroid Build Coastguard Worker }
149*acea8879SAndroid Build Coastguard Worker
150*acea8879SAndroid Build Coastguard Worker if (!oem_settings.empty()) {
151*acea8879SAndroid Build Coastguard Worker CHECK_EQ(0, access(oem_settings.c_str(), R_OK));
152*acea8879SAndroid Build Coastguard Worker source_build_info.SetOemSettings(oem_settings);
153*acea8879SAndroid Build Coastguard Worker }
154*acea8879SAndroid Build Coastguard Worker
155*acea8879SAndroid Build Coastguard Worker Updater updater(std::make_unique<SimulatorRuntime>(&source_build_info));
156*acea8879SAndroid Build Coastguard Worker if (!updater.Init(cmd_pipe.release(), package_name, false)) {
157*acea8879SAndroid Build Coastguard Worker return EXIT_FAILURE;
158*acea8879SAndroid Build Coastguard Worker }
159*acea8879SAndroid Build Coastguard Worker
160*acea8879SAndroid Build Coastguard Worker if (!updater.RunUpdate()) {
161*acea8879SAndroid Build Coastguard Worker return EXIT_FAILURE;
162*acea8879SAndroid Build Coastguard Worker }
163*acea8879SAndroid Build Coastguard Worker
164*acea8879SAndroid Build Coastguard Worker LOG(INFO) << "\nscript succeeded, result: " << updater.GetResult();
165*acea8879SAndroid Build Coastguard Worker
166*acea8879SAndroid Build Coastguard Worker return 0;
167*acea8879SAndroid Build Coastguard Worker }
168