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

Commit 38e8e745 authored by Jooyung Han's avatar Jooyung Han
Browse files

Use subcontext for APEX configs from /{vendor, odm}

Instead of using config file path, use APEX's preinstalled path to
determine whether to use subcontext or not for APEX configs.

Bug: 232021354
Test: CtsInitTestCases, CtsBluetoothTestCases
Change-Id: Iba603f09602f0bec3113e2be3d15c62055c09e72
parent 1eb3394e
Loading
Loading
Loading
Loading
+53 −5
Original line number Diff line number Diff line
@@ -85,6 +85,10 @@
#include "system/core/init/property_service.pb.h"
#include "util.h"

#ifndef RECOVERY
#include "com_android_apex.h"
#endif  // RECOVERY

using namespace std::chrono_literals;
using namespace std::string_literals;

@@ -293,14 +297,58 @@ Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
    return parser;
}

#ifndef RECOVERY
template <typename T>
struct LibXmlErrorHandler {
    T handler_;
    template <typename Handler>
    LibXmlErrorHandler(Handler&& handler) : handler_(std::move(handler)) {
        xmlSetGenericErrorFunc(nullptr, &ErrorHandler);
    }
    ~LibXmlErrorHandler() { xmlSetGenericErrorFunc(nullptr, nullptr); }
    static void ErrorHandler(void*, const char* msg, ...) {
        va_list args;
        va_start(args, msg);
        char* formatted;
        if (vasprintf(&formatted, msg, args) >= 0) {
            LOG(ERROR) << formatted;
        }
        free(formatted);
        va_end(args);
    }
};

template <typename Handler>
LibXmlErrorHandler(Handler&&) -> LibXmlErrorHandler<Handler>;
#endif  // RECOVERY

// Returns a Parser that accepts scripts from APEX modules. It supports `service` and `on`.
Parser CreateApexConfigParser(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser;

    parser.AddSectionParser(
            "service", std::make_unique<ServiceParser>(&service_list, GetSubcontext(), std::nullopt,
    auto subcontext = GetSubcontext();
#ifndef RECOVERY
    if (subcontext) {
        const auto apex_info_list_file = "/apex/apex-info-list.xml";
        auto error_handler = LibXmlErrorHandler([&](const auto& error_message) {
            LOG(ERROR) << "Failed to read " << apex_info_list_file << ":" << error_message;
        });
        const auto apex_info_list = com::android::apex::readApexInfoList(apex_info_list_file);
        if (apex_info_list.has_value()) {
            std::vector<std::string> subcontext_apexes;
            for (const auto& info : apex_info_list->getApexInfo()) {
                if (info.hasPreinstalledModulePath() &&
                    subcontext->PathMatchesSubcontext(info.getPreinstalledModulePath())) {
                    subcontext_apexes.push_back(info.getModuleName());
                }
            }
            subcontext->SetApexList(std::move(subcontext_apexes));
        }
    }
#endif  // RECOVERY
    parser.AddSectionParser("service",
                            std::make_unique<ServiceParser>(&service_list, subcontext, std::nullopt,
                                                            /*from_apex=*/true));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, subcontext));

    return parser;
}
+12 −1
Original line number Diff line number Diff line
@@ -250,7 +250,14 @@ void Subcontext::Restart() {
    Fork();
}

bool Subcontext::PathMatchesSubcontext(const std::string& path) {
bool Subcontext::PathMatchesSubcontext(const std::string& path) const {
    static const std::string kApexDir = "/apex/";
    if (StartsWith(path, kApexDir)) {
        auto begin = kApexDir.size();
        auto end = path.find('/', begin);
        auto apex_name = path.substr(begin, end - begin);
        return std::find(apex_list_.begin(), apex_list_.end(), apex_name) != apex_list_.end();
    }
    for (const auto& prefix : path_prefixes_) {
        if (StartsWith(path, prefix)) {
            return true;
@@ -259,6 +266,10 @@ bool Subcontext::PathMatchesSubcontext(const std::string& path) {
    return false;
}

void Subcontext::SetApexList(std::vector<std::string>&& apex_list) {
    apex_list_ = std::move(apex_list);
}

Result<SubcontextReply> Subcontext::TransmitMessage(const SubcontextCommand& subcontext_command) {
    if (auto result = SendMessage(socket_, subcontext_command); !result.ok()) {
        Restart();
+3 −1
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@ class Subcontext {
    Result<void> Execute(const std::vector<std::string>& args);
    Result<std::vector<std::string>> ExpandArgs(const std::vector<std::string>& args);
    void Restart();
    bool PathMatchesSubcontext(const std::string& path);
    bool PathMatchesSubcontext(const std::string& path) const;
    void SetApexList(std::vector<std::string>&& apex_list);

    const std::string& context() const { return context_; }
    pid_t pid() const { return pid_; }
@@ -56,6 +57,7 @@ class Subcontext {
    Result<SubcontextReply> TransmitMessage(const SubcontextCommand& subcontext_command);

    std::vector<std::string> path_prefixes_;
    std::vector<std::string> apex_list_;
    std::string context_;
    pid_t pid_;
    android::base::unique_fd socket_;