Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8fcd906 authored by Steven Moreland's avatar Steven Moreland Committed by android-build-merger
Browse files

Merge changes from topic "b69050941" am: 37eb97d9

am: 864a1baa

Change-Id: I676cce806836ef6a9204e7b482e94b8cb1d7163f
parents 9ecaaf44 864a1baa
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -379,10 +379,12 @@ Result<Success> ActionParser::ParseLineSection(std::vector<std::string>&& args,
    return action_ ? action_->AddCommand(std::move(args), line) : Success();
}

void ActionParser::EndSection() {
Result<Success> ActionParser::EndSection() {
    if (action_ && action_->NumCommands() > 0) {
        action_manager_->AddAction(std::move(action_));
    }

    return Success();
}

}  // namespace init
+1 −1
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ class ActionParser : public SectionParser {
    Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
                                 int line) override;
    Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
    void EndSection() override;
    Result<Success> EndSection() override;

  private:
    ActionManager* action_manager_;
+34 −6
Original line number Diff line number Diff line
@@ -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);
}
+16 −4
Original line number Diff line number Diff line
@@ -50,12 +50,24 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
    state.nexttoken = 0;

    SectionParser* section_parser = nullptr;
    int section_start_line = -1;
    std::vector<std::string> args;

    auto end_section = [&] {
        if (section_parser == nullptr) return;

        if (auto result = section_parser->EndSection(); !result) {
            LOG(ERROR) << filename << ": " << section_start_line << ": " << result.error();
        }

        section_parser = nullptr;
        section_start_line = -1;
    };

    for (;;) {
        switch (next_token(&state)) {
            case T_EOF:
                if (section_parser) section_parser->EndSection();
                end_section();
                return;
            case T_NEWLINE:
                state.line++;
@@ -65,18 +77,18 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
                // uevent.
                for (const auto& [prefix, callback] : line_callbacks_) {
                    if (android::base::StartsWith(args[0], prefix.c_str())) {
                        if (section_parser) section_parser->EndSection();
                        end_section();

                        if (auto result = callback(std::move(args)); !result) {
                            LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
                        }
                        section_parser = nullptr;
                        break;
                    }
                }
                if (section_parsers_.count(args[0])) {
                    if (section_parser) section_parser->EndSection();
                    end_section();
                    section_parser = section_parsers_[args[0]].get();
                    section_start_line = state.line;
                    if (auto result =
                            section_parser->ParseSection(std::move(args), filename, state.line);
                        !result) {
+8 −10
Original line number Diff line number Diff line
@@ -26,24 +26,22 @@

//  SectionParser is an interface that can parse a given 'section' in init.
//
//  You can implement up to 4 functions below, with ParseSection() being mandatory.
//  The first two function return bool with false indicating a failure and has a std::string* err
//  parameter into which an error string can be written.  It will be reported along with the
//  filename and line number of where the error occurred.
//  You can implement up to 4 functions below, with ParseSection being mandatory. The first two
//  functions return Result<Success> indicating if they have an error. It will be reported along
//  with the filename and line number of where the error occurred.
//
//  1) bool ParseSection(std::vector<std::string>&& args, const std::string& filename,
//                       int line, std::string* err)
//  1) ParseSection
//    This function is called when a section is first encountered.
//
//  2) bool ParseLineSection(std::vector<std::string>&& args, int line, std::string* err)
//  2) ParseLineSection
//    This function is called on each subsequent line until the next section is encountered.
//
//  3) bool EndSection()
//  3) EndSection
//    This function is called either when a new section is found or at the end of the file.
//    It indicates that parsing of the current section is complete and any relevant objects should
//    be committed.
//
//  4) bool EndFile()
//  4) EndFile
//    This function is called at the end of the file.
//    It indicates that the parsing has completed and any relevant objects should be committed.

@@ -56,7 +54,7 @@ class SectionParser {
    virtual Result<Success> ParseSection(std::vector<std::string>&& args,
                                         const std::string& filename, int line) = 0;
    virtual Result<Success> ParseLineSection(std::vector<std::string>&&, int) { return Success(); };
    virtual void EndSection(){};
    virtual Result<Success> EndSection() { return Success(); };
    virtual void EndFile(){};
};

Loading