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
This commit is contained in:
parent
1eb3394e9c
commit
38e8e74550
3 changed files with 68 additions and 7 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue