Move ActionManager to its own file

Bug: 36970783
Test: build
Change-Id: I08fa39052236b462249f79de1d02bf02bdbf4c84
This commit is contained in:
Tom Cherry 2018-02-13 15:36:14 -08:00
parent 0f6417f232
commit 7fd3bc27ec
10 changed files with 185 additions and 126 deletions

View file

@ -93,6 +93,7 @@ cc_library_static {
defaults: ["init_defaults"],
srcs: [
"action.cpp",
"action_manager.cpp",
"action_parser.cpp",
"bootchart.cpp",
"builtins.cpp",

View file

@ -281,103 +281,5 @@ void Action::DumpState() const {
}
}
ActionManager::ActionManager() : current_command_(0) {
}
ActionManager& ActionManager::GetInstance() {
static ActionManager instance;
return instance;
}
void ActionManager::AddAction(std::unique_ptr<Action> action) {
actions_.emplace_back(std::move(action));
}
void ActionManager::QueueEventTrigger(const std::string& trigger) {
event_queue_.emplace(trigger);
}
void ActionManager::QueuePropertyChange(const std::string& name, const std::string& value) {
event_queue_.emplace(std::make_pair(name, value));
}
void ActionManager::QueueAllPropertyActions() {
QueuePropertyChange("", "");
}
void ActionManager::QueueBuiltinAction(BuiltinFunction func, const std::string& name) {
auto action = std::make_unique<Action>(true, nullptr, "<Builtin Action>", 0);
std::vector<std::string> name_vector{name};
if (auto result = action->InitSingleTrigger(name); !result) {
LOG(ERROR) << "Cannot queue BuiltinAction for " << name << ": " << result.error();
return;
}
action->AddCommand(func, name_vector, 0);
event_queue_.emplace(action.get());
actions_.emplace_back(std::move(action));
}
void ActionManager::ExecuteOneCommand() {
// Loop through the event queue until we have an action to execute
while (current_executing_actions_.empty() && !event_queue_.empty()) {
for (const auto& action : actions_) {
if (std::visit([&action](const auto& event) { return action->CheckEvent(event); },
event_queue_.front())) {
current_executing_actions_.emplace(action.get());
}
}
event_queue_.pop();
}
if (current_executing_actions_.empty()) {
return;
}
auto action = current_executing_actions_.front();
if (current_command_ == 0) {
std::string trigger_name = action->BuildTriggersString();
LOG(INFO) << "processing action (" << trigger_name << ") from (" << action->filename()
<< ":" << action->line() << ")";
}
action->ExecuteOneCommand(current_command_);
// If this was the last command in the current action, then remove
// the action from the executing list.
// If this action was oneshot, then also remove it from actions_.
++current_command_;
if (current_command_ == action->NumCommands()) {
current_executing_actions_.pop();
current_command_ = 0;
if (action->oneshot()) {
auto eraser = [&action] (std::unique_ptr<Action>& a) {
return a.get() == action;
};
actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser));
}
}
}
bool ActionManager::HasMoreCommands() const {
return !current_executing_actions_.empty() || !event_queue_.empty();
}
void ActionManager::DumpState() const {
for (const auto& a : actions_) {
a->DumpState();
}
}
void ActionManager::ClearQueue() {
// We are shutting down so don't claim the oneshot builtin actions back
current_executing_actions_ = {};
event_queue_ = {};
current_command_ = 0;
}
} // namespace init
} // namespace android

View file

@ -95,33 +95,6 @@ class Action {
static const KeywordFunctionMap* function_map_;
};
class ActionManager {
public:
static ActionManager& GetInstance();
// Exposed for testing
ActionManager();
void AddAction(std::unique_ptr<Action> action);
void QueueEventTrigger(const std::string& trigger);
void QueuePropertyChange(const std::string& name, const std::string& value);
void QueueAllPropertyActions();
void QueueBuiltinAction(BuiltinFunction func, const std::string& name);
void ExecuteOneCommand();
bool HasMoreCommands() const;
void DumpState() const;
void ClearQueue();
private:
ActionManager(ActionManager const&) = delete;
void operator=(ActionManager const&) = delete;
std::vector<std::unique_ptr<Action>> actions_;
std::queue<std::variant<EventTrigger, PropertyChange, BuiltinAction>> event_queue_;
std::queue<const Action*> current_executing_actions_;
std::size_t current_command_;
};
} // namespace init
} // namespace android

120
init/action_manager.cpp Normal file
View file

@ -0,0 +1,120 @@
/*
* Copyright (C) 2018 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 "action_manager.h"
#include <android-base/logging.h>
namespace android {
namespace init {
ActionManager::ActionManager() : current_command_(0) {}
ActionManager& ActionManager::GetInstance() {
static ActionManager instance;
return instance;
}
void ActionManager::AddAction(std::unique_ptr<Action> action) {
actions_.emplace_back(std::move(action));
}
void ActionManager::QueueEventTrigger(const std::string& trigger) {
event_queue_.emplace(trigger);
}
void ActionManager::QueuePropertyChange(const std::string& name, const std::string& value) {
event_queue_.emplace(std::make_pair(name, value));
}
void ActionManager::QueueAllPropertyActions() {
QueuePropertyChange("", "");
}
void ActionManager::QueueBuiltinAction(BuiltinFunction func, const std::string& name) {
auto action = std::make_unique<Action>(true, nullptr, "<Builtin Action>", 0);
std::vector<std::string> name_vector{name};
if (auto result = action->InitSingleTrigger(name); !result) {
LOG(ERROR) << "Cannot queue BuiltinAction for " << name << ": " << result.error();
return;
}
action->AddCommand(func, name_vector, 0);
event_queue_.emplace(action.get());
actions_.emplace_back(std::move(action));
}
void ActionManager::ExecuteOneCommand() {
// Loop through the event queue until we have an action to execute
while (current_executing_actions_.empty() && !event_queue_.empty()) {
for (const auto& action : actions_) {
if (std::visit([&action](const auto& event) { return action->CheckEvent(event); },
event_queue_.front())) {
current_executing_actions_.emplace(action.get());
}
}
event_queue_.pop();
}
if (current_executing_actions_.empty()) {
return;
}
auto action = current_executing_actions_.front();
if (current_command_ == 0) {
std::string trigger_name = action->BuildTriggersString();
LOG(INFO) << "processing action (" << trigger_name << ") from (" << action->filename()
<< ":" << action->line() << ")";
}
action->ExecuteOneCommand(current_command_);
// If this was the last command in the current action, then remove
// the action from the executing list.
// If this action was oneshot, then also remove it from actions_.
++current_command_;
if (current_command_ == action->NumCommands()) {
current_executing_actions_.pop();
current_command_ = 0;
if (action->oneshot()) {
auto eraser = [&action](std::unique_ptr<Action>& a) { return a.get() == action; };
actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser));
}
}
}
bool ActionManager::HasMoreCommands() const {
return !current_executing_actions_.empty() || !event_queue_.empty();
}
void ActionManager::DumpState() const {
for (const auto& a : actions_) {
a->DumpState();
}
}
void ActionManager::ClearQueue() {
// We are shutting down so don't claim the oneshot builtin actions back
current_executing_actions_ = {};
event_queue_ = {};
current_command_ = 0;
}
} // namespace init
} // namespace android

59
init/action_manager.h Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (C) 2018 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.
*/
#ifndef _INIT_ACTION_MANAGER_H
#define _INIT_ACTION_MANAGER_H
#include <string>
#include <vector>
#include "action.h"
#include "builtins.h"
namespace android {
namespace init {
class ActionManager {
public:
static ActionManager& GetInstance();
// Exposed for testing
ActionManager();
void AddAction(std::unique_ptr<Action> action);
void QueueEventTrigger(const std::string& trigger);
void QueuePropertyChange(const std::string& name, const std::string& value);
void QueueAllPropertyActions();
void QueueBuiltinAction(BuiltinFunction func, const std::string& name);
void ExecuteOneCommand();
bool HasMoreCommands() const;
void DumpState() const;
void ClearQueue();
private:
ActionManager(ActionManager const&) = delete;
void operator=(ActionManager const&) = delete;
std::vector<std::unique_ptr<Action>> actions_;
std::queue<std::variant<EventTrigger, PropertyChange, BuiltinAction>> event_queue_;
std::queue<const Action*> current_executing_actions_;
std::size_t current_command_;
};
} // namespace init
} // namespace android
#endif

View file

@ -21,6 +21,7 @@
#include <vector>
#include "action.h"
#include "action_manager.h"
#include "parser.h"
#include "subcontext.h"

View file

@ -58,7 +58,7 @@
#include <selinux/selinux.h>
#include <system/thread_defs.h>
#include "action.h"
#include "action_manager.h"
#include "bootchart.h"
#include "init.h"
#include "parser.h"

View file

@ -21,6 +21,7 @@
#include <vector>
#include "action.h"
#include "action_manager.h"
#include "parser.h"
#include "service.h"

View file

@ -21,6 +21,7 @@
#include <gtest/gtest.h>
#include "action.h"
#include "action_manager.h"
#include "action_parser.h"
#include "builtins.h"
#include "import_parser.h"

View file

@ -50,6 +50,7 @@
#include <private/android_filesystem_config.h>
#include <selinux/selinux.h>
#include "action_manager.h"
#include "capabilities.h"
#include "init.h"
#include "property_service.h"