Split out ServiceList and ServiceParser from service.cpp/.h
These always should have been in their own files. Test: build Change-Id: I201109b5ee63016e78901bbfd404846d45e1d4e6
This commit is contained in:
parent
c0349199db
commit
2aeb1addee
14 changed files with 351 additions and 218 deletions
|
|
@ -128,6 +128,8 @@ cc_library_static {
|
|||
"selabel.cpp",
|
||||
"selinux.cpp",
|
||||
"service.cpp",
|
||||
"service_list.cpp",
|
||||
"service_parser.cpp",
|
||||
"service_utils.cpp",
|
||||
"sigchld_handler.cpp",
|
||||
"subcontext.cpp",
|
||||
|
|
@ -260,6 +262,8 @@ cc_binary {
|
|||
"rlimit_parser.cpp",
|
||||
"tokenizer.cpp",
|
||||
"service.cpp",
|
||||
"service_list.cpp",
|
||||
"service_parser.cpp",
|
||||
"service_utils.cpp",
|
||||
"subcontext.cpp",
|
||||
"subcontext.proto",
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
#include "selabel.h"
|
||||
#include "selinux.h"
|
||||
#include "service.h"
|
||||
#include "service_list.h"
|
||||
#include "subcontext.h"
|
||||
#include "util.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#include "parser.h"
|
||||
#include "result.h"
|
||||
#include "service.h"
|
||||
#include "service_list.h"
|
||||
#include "service_parser.h"
|
||||
|
||||
#define EXCLUDE_FS_CONFIG_STRUCTURES
|
||||
#include "generated_android_ids.h"
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@
|
|||
#include "security.h"
|
||||
#include "selabel.h"
|
||||
#include "selinux.h"
|
||||
#include "service.h"
|
||||
#include "service_parser.h"
|
||||
#include "sigchld_handler.h"
|
||||
#include "util.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include "action.h"
|
||||
#include "action_manager.h"
|
||||
#include "parser.h"
|
||||
#include "service.h"
|
||||
#include "service_list.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include "keyword_map.h"
|
||||
#include "parser.h"
|
||||
#include "service.h"
|
||||
#include "service_list.h"
|
||||
#include "service_parser.h"
|
||||
#include "test_function_map.h"
|
||||
#include "util.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "property_service.h"
|
||||
#include "reboot_utils.h"
|
||||
#include "service.h"
|
||||
#include "service_list.h"
|
||||
#include "sigchld_handler.h"
|
||||
|
||||
#define PROC_SYSRQ "/proc/sysrq-trigger"
|
||||
|
|
|
|||
146
init/service.cpp
146
init/service.cpp
|
|
@ -40,6 +40,7 @@
|
|||
#include <system/thread_defs.h>
|
||||
|
||||
#include "rlimit_parser.h"
|
||||
#include "service_list.h"
|
||||
#include "util.h"
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
|
@ -1072,17 +1073,6 @@ void Service::StopOrReset(int how) {
|
|||
}
|
||||
}
|
||||
|
||||
ServiceList::ServiceList() {}
|
||||
|
||||
ServiceList& ServiceList::GetInstance() {
|
||||
static ServiceList instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void ServiceList::AddService(std::unique_ptr<Service> service) {
|
||||
services_.emplace_back(std::move(service));
|
||||
}
|
||||
|
||||
std::unique_ptr<Service> Service::MakeTemporaryOneshotService(const std::vector<std::string>& args) {
|
||||
// Parse the arguments: exec [SECLABEL [UID [GID]*] --] COMMAND ARGS...
|
||||
// SECLABEL can be a - to denote default
|
||||
|
|
@ -1147,139 +1137,5 @@ std::unique_ptr<Service> Service::MakeTemporaryOneshotService(const std::vector<
|
|||
nullptr, str_args);
|
||||
}
|
||||
|
||||
// Shutdown services in the opposite order that they were started.
|
||||
const std::vector<Service*> ServiceList::services_in_shutdown_order() const {
|
||||
std::vector<Service*> shutdown_services;
|
||||
for (const auto& service : services_) {
|
||||
if (service->start_order() > 0) shutdown_services.emplace_back(service.get());
|
||||
}
|
||||
std::sort(shutdown_services.begin(), shutdown_services.end(),
|
||||
[](const auto& a, const auto& b) { return a->start_order() > b->start_order(); });
|
||||
return shutdown_services;
|
||||
}
|
||||
|
||||
void ServiceList::RemoveService(const Service& svc) {
|
||||
auto svc_it = std::find_if(services_.begin(), services_.end(),
|
||||
[&svc] (const std::unique_ptr<Service>& s) {
|
||||
return svc.name() == s->name();
|
||||
});
|
||||
if (svc_it == services_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
services_.erase(svc_it);
|
||||
}
|
||||
|
||||
void ServiceList::DumpState() const {
|
||||
for (const auto& s : services_) {
|
||||
s->DumpState();
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceList::MarkPostData() {
|
||||
post_data_ = true;
|
||||
}
|
||||
|
||||
bool ServiceList::IsPostData() {
|
||||
return post_data_;
|
||||
}
|
||||
|
||||
void ServiceList::MarkServicesUpdate() {
|
||||
services_update_finished_ = true;
|
||||
|
||||
// start the delayed services
|
||||
for (const auto& name : delayed_service_names_) {
|
||||
Service* service = FindService(name);
|
||||
if (service == nullptr) {
|
||||
LOG(ERROR) << "delayed service '" << name << "' could not be found.";
|
||||
continue;
|
||||
}
|
||||
if (auto result = service->Start(); !result) {
|
||||
LOG(ERROR) << result.error().message();
|
||||
}
|
||||
}
|
||||
delayed_service_names_.clear();
|
||||
}
|
||||
|
||||
void ServiceList::DelayService(const Service& service) {
|
||||
if (services_update_finished_) {
|
||||
LOG(ERROR) << "Cannot delay the start of service '" << service.name()
|
||||
<< "' because all services are already updated. Ignoring.";
|
||||
return;
|
||||
}
|
||||
delayed_service_names_.emplace_back(service.name());
|
||||
}
|
||||
|
||||
Result<void> ServiceParser::ParseSection(std::vector<std::string>&& args,
|
||||
const std::string& filename, int line) {
|
||||
if (args.size() < 3) {
|
||||
return Error() << "services must have a name and a program";
|
||||
}
|
||||
|
||||
const std::string& name = args[1];
|
||||
if (!IsValidName(name)) {
|
||||
return Error() << "invalid service name '" << name << "'";
|
||||
}
|
||||
|
||||
filename_ = filename;
|
||||
|
||||
Subcontext* restart_action_subcontext = nullptr;
|
||||
if (subcontexts_) {
|
||||
for (auto& subcontext : *subcontexts_) {
|
||||
if (StartsWith(filename, subcontext.path_prefix())) {
|
||||
restart_action_subcontext = &subcontext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> str_args(args.begin() + 2, args.end());
|
||||
|
||||
if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_P__) {
|
||||
if (str_args[0] == "/sbin/watchdogd") {
|
||||
str_args[0] = "/system/bin/watchdogd";
|
||||
}
|
||||
}
|
||||
|
||||
service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line) {
|
||||
return service_ ? service_->ParseLine(std::move(args)) : Result<void>{};
|
||||
}
|
||||
|
||||
Result<void> ServiceParser::EndSection() {
|
||||
if (service_) {
|
||||
Service* old_service = service_list_->FindService(service_->name());
|
||||
if (old_service) {
|
||||
if (!service_->is_override()) {
|
||||
return Error() << "ignored duplicate definition of service '" << service_->name()
|
||||
<< "'";
|
||||
}
|
||||
|
||||
if (StartsWith(filename_, "/apex/") && !old_service->is_updatable()) {
|
||||
return Error() << "cannot update a non-updatable service '" << service_->name()
|
||||
<< "' with a config in APEX";
|
||||
}
|
||||
|
||||
service_list_->RemoveService(*old_service);
|
||||
old_service = nullptr;
|
||||
}
|
||||
|
||||
service_list_->AddService(std::move(service_));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ServiceParser::IsValidName(const std::string& name) const {
|
||||
// Property names can be any length, but may only contain certain characters.
|
||||
// Property values can contain any characters, but may only be a certain length.
|
||||
// (The latter restriction is needed because `start` and `stop` work by writing
|
||||
// the service name to the "ctl.start" and "ctl.stop" properties.)
|
||||
return IsLegalPropertyName("init.svc." + name) && name.size() <= PROP_VALUE_MAX;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
|||
|
|
@ -238,78 +238,6 @@ class Service {
|
|||
bool running_at_post_data_reset_ = false;
|
||||
};
|
||||
|
||||
class ServiceList {
|
||||
public:
|
||||
static ServiceList& GetInstance();
|
||||
|
||||
// Exposed for testing
|
||||
ServiceList();
|
||||
|
||||
void AddService(std::unique_ptr<Service> service);
|
||||
void RemoveService(const Service& svc);
|
||||
|
||||
template <typename T, typename F = decltype(&Service::name)>
|
||||
Service* FindService(T value, F function = &Service::name) const {
|
||||
auto svc = std::find_if(services_.begin(), services_.end(),
|
||||
[&function, &value](const std::unique_ptr<Service>& s) {
|
||||
return std::invoke(function, s) == value;
|
||||
});
|
||||
if (svc != services_.end()) {
|
||||
return svc->get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Service* FindInterface(const std::string& interface_name) {
|
||||
for (const auto& svc : services_) {
|
||||
if (svc->interfaces().count(interface_name) > 0) {
|
||||
return svc.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DumpState() const;
|
||||
|
||||
auto begin() const { return services_.begin(); }
|
||||
auto end() const { return services_.end(); }
|
||||
const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
|
||||
const std::vector<Service*> services_in_shutdown_order() const;
|
||||
|
||||
void MarkPostData();
|
||||
bool IsPostData();
|
||||
void MarkServicesUpdate();
|
||||
bool IsServicesUpdated() const { return services_update_finished_; }
|
||||
void DelayService(const Service& service);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Service>> services_;
|
||||
|
||||
bool post_data_ = false;
|
||||
bool services_update_finished_ = false;
|
||||
std::vector<std::string> delayed_service_names_;
|
||||
};
|
||||
|
||||
class ServiceParser : public SectionParser {
|
||||
public:
|
||||
ServiceParser(ServiceList* service_list, std::vector<Subcontext>* subcontexts)
|
||||
: service_list_(service_list), subcontexts_(subcontexts), service_(nullptr) {}
|
||||
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line) override;
|
||||
Result<void> ParseLineSection(std::vector<std::string>&& args, int line) override;
|
||||
Result<void> EndSection() override;
|
||||
void EndFile() override { filename_ = ""; }
|
||||
|
||||
private:
|
||||
bool IsValidName(const std::string& name) const;
|
||||
|
||||
ServiceList* service_list_;
|
||||
std::vector<Subcontext>* subcontexts_;
|
||||
std::unique_ptr<Service> service_;
|
||||
std::string filename_;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
|
|
|
|||
98
init/service_list.cpp
Normal file
98
init/service_list.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "service_list.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
ServiceList::ServiceList() {}
|
||||
|
||||
ServiceList& ServiceList::GetInstance() {
|
||||
static ServiceList instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void ServiceList::AddService(std::unique_ptr<Service> service) {
|
||||
services_.emplace_back(std::move(service));
|
||||
}
|
||||
|
||||
// Shutdown services in the opposite order that they were started.
|
||||
const std::vector<Service*> ServiceList::services_in_shutdown_order() const {
|
||||
std::vector<Service*> shutdown_services;
|
||||
for (const auto& service : services_) {
|
||||
if (service->start_order() > 0) shutdown_services.emplace_back(service.get());
|
||||
}
|
||||
std::sort(shutdown_services.begin(), shutdown_services.end(),
|
||||
[](const auto& a, const auto& b) { return a->start_order() > b->start_order(); });
|
||||
return shutdown_services;
|
||||
}
|
||||
|
||||
void ServiceList::RemoveService(const Service& svc) {
|
||||
auto svc_it = std::find_if(
|
||||
services_.begin(), services_.end(),
|
||||
[&svc](const std::unique_ptr<Service>& s) { return svc.name() == s->name(); });
|
||||
if (svc_it == services_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
services_.erase(svc_it);
|
||||
}
|
||||
|
||||
void ServiceList::DumpState() const {
|
||||
for (const auto& s : services_) {
|
||||
s->DumpState();
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceList::MarkPostData() {
|
||||
post_data_ = true;
|
||||
}
|
||||
|
||||
bool ServiceList::IsPostData() {
|
||||
return post_data_;
|
||||
}
|
||||
|
||||
void ServiceList::MarkServicesUpdate() {
|
||||
services_update_finished_ = true;
|
||||
|
||||
// start the delayed services
|
||||
for (const auto& name : delayed_service_names_) {
|
||||
Service* service = FindService(name);
|
||||
if (service == nullptr) {
|
||||
LOG(ERROR) << "delayed service '" << name << "' could not be found.";
|
||||
continue;
|
||||
}
|
||||
if (auto result = service->Start(); !result) {
|
||||
LOG(ERROR) << result.error().message();
|
||||
}
|
||||
}
|
||||
delayed_service_names_.clear();
|
||||
}
|
||||
|
||||
void ServiceList::DelayService(const Service& service) {
|
||||
if (services_update_finished_) {
|
||||
LOG(ERROR) << "Cannot delay the start of service '" << service.name()
|
||||
<< "' because all services are already updated. Ignoring.";
|
||||
return;
|
||||
}
|
||||
delayed_service_names_.emplace_back(service.name());
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
81
init/service_list.h
Normal file
81
init/service_list.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "service.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class ServiceList {
|
||||
public:
|
||||
static ServiceList& GetInstance();
|
||||
|
||||
// Exposed for testing
|
||||
ServiceList();
|
||||
|
||||
void AddService(std::unique_ptr<Service> service);
|
||||
void RemoveService(const Service& svc);
|
||||
|
||||
template <typename T, typename F = decltype(&Service::name)>
|
||||
Service* FindService(T value, F function = &Service::name) const {
|
||||
auto svc = std::find_if(services_.begin(), services_.end(),
|
||||
[&function, &value](const std::unique_ptr<Service>& s) {
|
||||
return std::invoke(function, s) == value;
|
||||
});
|
||||
if (svc != services_.end()) {
|
||||
return svc->get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Service* FindInterface(const std::string& interface_name) {
|
||||
for (const auto& svc : services_) {
|
||||
if (svc->interfaces().count(interface_name) > 0) {
|
||||
return svc.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DumpState() const;
|
||||
|
||||
auto begin() const { return services_.begin(); }
|
||||
auto end() const { return services_.end(); }
|
||||
const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
|
||||
const std::vector<Service*> services_in_shutdown_order() const;
|
||||
|
||||
void MarkPostData();
|
||||
bool IsPostData();
|
||||
void MarkServicesUpdate();
|
||||
bool IsServicesUpdated() const { return services_update_finished_; }
|
||||
void DelayService(const Service& service);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Service>> services_;
|
||||
|
||||
bool post_data_ = false;
|
||||
bool services_update_finished_ = false;
|
||||
std::vector<std::string> delayed_service_names_;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
108
init/service_parser.cpp
Normal file
108
init/service_parser.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "service_parser.h"
|
||||
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <sys/system_properties.h>
|
||||
|
||||
#include "selinux.h"
|
||||
#else
|
||||
#include "host_init_stubs.h"
|
||||
#endif
|
||||
|
||||
using android::base::StartsWith;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
Result<void> ServiceParser::ParseSection(std::vector<std::string>&& args,
|
||||
const std::string& filename, int line) {
|
||||
if (args.size() < 3) {
|
||||
return Error() << "services must have a name and a program";
|
||||
}
|
||||
|
||||
const std::string& name = args[1];
|
||||
if (!IsValidName(name)) {
|
||||
return Error() << "invalid service name '" << name << "'";
|
||||
}
|
||||
|
||||
filename_ = filename;
|
||||
|
||||
Subcontext* restart_action_subcontext = nullptr;
|
||||
if (subcontexts_) {
|
||||
for (auto& subcontext : *subcontexts_) {
|
||||
if (StartsWith(filename, subcontext.path_prefix())) {
|
||||
restart_action_subcontext = &subcontext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> str_args(args.begin() + 2, args.end());
|
||||
|
||||
if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_P__) {
|
||||
if (str_args[0] == "/sbin/watchdogd") {
|
||||
str_args[0] = "/system/bin/watchdogd";
|
||||
}
|
||||
}
|
||||
|
||||
service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line) {
|
||||
return service_ ? service_->ParseLine(std::move(args)) : Result<void>{};
|
||||
}
|
||||
|
||||
Result<void> ServiceParser::EndSection() {
|
||||
if (service_) {
|
||||
Service* old_service = service_list_->FindService(service_->name());
|
||||
if (old_service) {
|
||||
if (!service_->is_override()) {
|
||||
return Error() << "ignored duplicate definition of service '" << service_->name()
|
||||
<< "'";
|
||||
}
|
||||
|
||||
if (StartsWith(filename_, "/apex/") && !old_service->is_updatable()) {
|
||||
return Error() << "cannot update a non-updatable service '" << service_->name()
|
||||
<< "' with a config in APEX";
|
||||
}
|
||||
|
||||
service_list_->RemoveService(*old_service);
|
||||
old_service = nullptr;
|
||||
}
|
||||
|
||||
service_list_->AddService(std::move(service_));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ServiceParser::IsValidName(const std::string& name) const {
|
||||
// Property names can be any length, but may only contain certain characters.
|
||||
// Property values can contain any characters, but may only be a certain length.
|
||||
// (The latter restriction is needed because `start` and `stop` work by writing
|
||||
// the service name to the "ctl.start" and "ctl.stop" properties.)
|
||||
return IsLegalPropertyName("init.svc." + name) && name.size() <= PROP_VALUE_MAX;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
49
init/service_parser.h
Normal file
49
init/service_parser.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "parser.h"
|
||||
#include "service.h"
|
||||
#include "service_list.h"
|
||||
#include "subcontext.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class ServiceParser : public SectionParser {
|
||||
public:
|
||||
ServiceParser(ServiceList* service_list, std::vector<Subcontext>* subcontexts)
|
||||
: service_list_(service_list), subcontexts_(subcontexts), service_(nullptr) {}
|
||||
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line) override;
|
||||
Result<void> ParseLineSection(std::vector<std::string>&& args, int line) override;
|
||||
Result<void> EndSection() override;
|
||||
void EndFile() override { filename_ = ""; }
|
||||
|
||||
private:
|
||||
bool IsValidName(const std::string& name) const;
|
||||
|
||||
ServiceList* service_list_;
|
||||
std::vector<Subcontext>* subcontexts_;
|
||||
std::unique_ptr<Service> service_;
|
||||
std::string filename_;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "init.h"
|
||||
#include "service.h"
|
||||
#include "service_list.h"
|
||||
|
||||
using android::base::StringPrintf;
|
||||
using android::base::boot_clock;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue