Allow a service to override another.
For instance, on vendor.img: service foo /vendor/bin/nfc ... And then on odm.img: service foo /odm/bin/super-nfc override Allows a service on ODM to override a HAL on vendor. Bug: 69050941 Test: boot, init_tests Change-Id: I4e908fb66e89fc6e021799fe1fa6603d3072d62a
This commit is contained in:
parent
5e1bea30b9
commit
6f5333a4a9
|
@ -25,6 +25,7 @@
|
|||
#include "import_parser.h"
|
||||
#include "keyword_map.h"
|
||||
#include "parser.h"
|
||||
#include "service.h"
|
||||
#include "test_function_map.h"
|
||||
#include "util.h"
|
||||
|
||||
|
@ -34,12 +35,13 @@ namespace init {
|
|||
using ActionManagerCommand = std::function<void(ActionManager&)>;
|
||||
|
||||
void TestInit(const std::string& init_script_file, const TestFunctionMap& test_function_map,
|
||||
const std::vector<ActionManagerCommand>& commands) {
|
||||
const std::vector<ActionManagerCommand>& commands, ServiceList* service_list) {
|
||||
ActionManager am;
|
||||
|
||||
Action::set_function_map(&test_function_map);
|
||||
|
||||
Parser parser;
|
||||
parser.AddSectionParser("service", std::make_unique<ServiceParser>(service_list, nullptr));
|
||||
parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr));
|
||||
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
|
||||
|
||||
|
@ -55,11 +57,11 @@ void TestInit(const std::string& init_script_file, const TestFunctionMap& test_f
|
|||
}
|
||||
|
||||
void TestInitText(const std::string& init_script, const TestFunctionMap& test_function_map,
|
||||
const std::vector<ActionManagerCommand>& commands) {
|
||||
const std::vector<ActionManagerCommand>& commands, ServiceList* service_list) {
|
||||
TemporaryFile tf;
|
||||
ASSERT_TRUE(tf.fd != -1);
|
||||
ASSERT_TRUE(android::base::WriteStringToFd(init_script, tf.fd));
|
||||
TestInit(tf.path, test_function_map, commands);
|
||||
TestInit(tf.path, test_function_map, commands, service_list);
|
||||
}
|
||||
|
||||
TEST(init, SimpleEventTrigger) {
|
||||
|
@ -76,7 +78,8 @@ pass_test
|
|||
ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); };
|
||||
std::vector<ActionManagerCommand> commands{trigger_boot};
|
||||
|
||||
TestInitText(init_script, test_function_map, commands);
|
||||
ServiceList service_list;
|
||||
TestInitText(init_script, test_function_map, commands, &service_list);
|
||||
|
||||
EXPECT_TRUE(expect_true);
|
||||
}
|
||||
|
@ -104,7 +107,30 @@ execute_third
|
|||
ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); };
|
||||
std::vector<ActionManagerCommand> commands{trigger_boot};
|
||||
|
||||
TestInitText(init_script, test_function_map, commands);
|
||||
ServiceList service_list;
|
||||
TestInitText(init_script, test_function_map, commands, &service_list);
|
||||
}
|
||||
|
||||
TEST(init, OverrideService) {
|
||||
std::string init_script = R"init(
|
||||
service A something
|
||||
class first
|
||||
|
||||
service A something
|
||||
class second
|
||||
override
|
||||
|
||||
)init";
|
||||
|
||||
ServiceList service_list;
|
||||
TestInitText(init_script, TestFunctionMap(), {}, &service_list);
|
||||
ASSERT_EQ(1, std::distance(service_list.begin(), service_list.end()));
|
||||
|
||||
auto service = service_list.begin()->get();
|
||||
ASSERT_NE(nullptr, service);
|
||||
EXPECT_EQ(std::set<std::string>({"second"}), service->classnames());
|
||||
EXPECT_EQ("A", service->name());
|
||||
EXPECT_TRUE(service->is_override());
|
||||
}
|
||||
|
||||
TEST(init, EventTriggerOrderMultipleFiles) {
|
||||
|
@ -162,7 +188,9 @@ TEST(init, EventTriggerOrderMultipleFiles) {
|
|||
ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); };
|
||||
std::vector<ActionManagerCommand> commands{trigger_boot};
|
||||
|
||||
TestInit(start.path, test_function_map, commands);
|
||||
ServiceList service_list;
|
||||
|
||||
TestInit(start.path, test_function_map, commands, &service_list);
|
||||
|
||||
EXPECT_EQ(6, num_executed);
|
||||
}
|
||||
|
|
|
@ -530,6 +530,11 @@ Result<Success> Service::ParseOomScoreAdjust(const std::vector<std::string>& arg
|
|||
return Success();
|
||||
}
|
||||
|
||||
Result<Success> Service::ParseOverride(const std::vector<std::string>& args) {
|
||||
override_ = true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
Result<Success> Service::ParseMemcgSwappiness(const std::vector<std::string>& args) {
|
||||
if (!ParseInt(args[1], &swappiness_, 0)) {
|
||||
return Error() << "swappiness value must be equal or greater than 0";
|
||||
|
@ -671,6 +676,7 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
|
|||
{"keycodes", {1, kMax, &Service::ParseKeycodes}},
|
||||
{"oneshot", {0, 0, &Service::ParseOneshot}},
|
||||
{"onrestart", {1, kMax, &Service::ParseOnrestart}},
|
||||
{"override", {0, 0, &Service::ParseOverride}},
|
||||
{"oom_score_adjust",
|
||||
{1, 1, &Service::ParseOomScoreAdjust}},
|
||||
{"memcg.swappiness",
|
||||
|
@ -1134,7 +1140,13 @@ Result<Success> ServiceParser::EndSection() {
|
|||
if (service_) {
|
||||
Service* old_service = service_list_->FindService(service_->name());
|
||||
if (old_service) {
|
||||
return Error() << "ignored duplicate definition of service '" << service_->name() << "'";
|
||||
if (!service_->is_override()) {
|
||||
return Error() << "ignored duplicate definition of service '" << service_->name()
|
||||
<< "'";
|
||||
}
|
||||
|
||||
service_list_->RemoveService(*old_service);
|
||||
old_service = nullptr;
|
||||
}
|
||||
|
||||
service_list_->AddService(std::move(service_));
|
||||
|
|
|
@ -111,6 +111,7 @@ class Service {
|
|||
const std::set<std::string>& interfaces() const { return interfaces_; }
|
||||
int priority() const { return priority_; }
|
||||
int oom_score_adjust() const { return oom_score_adjust_; }
|
||||
bool is_override() const { return override_; }
|
||||
bool process_cgroup_empty() const { return process_cgroup_empty_; }
|
||||
unsigned long start_order() const { return start_order_; }
|
||||
const std::vector<std::string>& args() const { return args_; }
|
||||
|
@ -139,6 +140,7 @@ class Service {
|
|||
Result<Success> ParseOneshot(const std::vector<std::string>& args);
|
||||
Result<Success> ParseOnrestart(const std::vector<std::string>& args);
|
||||
Result<Success> ParseOomScoreAdjust(const std::vector<std::string>& args);
|
||||
Result<Success> ParseOverride(const std::vector<std::string>& args);
|
||||
Result<Success> ParseMemcgLimitInBytes(const std::vector<std::string>& args);
|
||||
Result<Success> ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args);
|
||||
Result<Success> ParseMemcgSwappiness(const std::vector<std::string>& args);
|
||||
|
@ -201,6 +203,8 @@ class Service {
|
|||
|
||||
bool process_cgroup_empty_ = false;
|
||||
|
||||
bool override_ = false;
|
||||
|
||||
unsigned long start_order_;
|
||||
|
||||
std::vector<std::pair<int, rlimit>> rlimits_;
|
||||
|
|
Loading…
Reference in New Issue