Merge changes from topics "action-in-apex-config", "apex-ready-event", "subcontext-for-vendor-apex" am: ec76b5cb4e

Original change: https://android-review.googlesource.com/c/platform/system/core/+/2093006

Change-Id: I6a5af004ea93fa333138f38cdb7c859c445cfa0d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Jooyung Han 2022-05-13 03:13:16 +00:00 committed by Automerger Merge Worker
commit 364bc73186
3 changed files with 68 additions and 7 deletions

View file

@ -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,
/*from_apex=*/true));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
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, subcontext));
return parser;
}

View file

@ -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();

View file

@ -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_;