diff options
-rw-r--r-- | init/Android.bp | 1 | ||||
-rw-r--r-- | init/action.cpp | 98 | ||||
-rw-r--r-- | init/action.h | 27 | ||||
-rw-r--r-- | init/action_manager.cpp | 120 | ||||
-rw-r--r-- | init/action_manager.h | 59 | ||||
-rw-r--r-- | init/action_parser.h | 1 | ||||
-rw-r--r-- | init/builtins.cpp | 2 | ||||
-rw-r--r-- | init/init.h | 1 | ||||
-rw-r--r-- | init/init_test.cpp | 1 | ||||
-rw-r--r-- | init/reboot.cpp | 1 |
10 files changed, 185 insertions, 126 deletions
diff --git a/init/Android.bp b/init/Android.bp index e218d2aa6..1f2ad2e78 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -93,6 +93,7 @@ cc_library_static { defaults: ["init_defaults"], srcs: [ "action.cpp", + "action_manager.cpp", "action_parser.cpp", "bootchart.cpp", "builtins.cpp", diff --git a/init/action.cpp b/init/action.cpp index 3fdff43a6..05b484f51 100644 --- a/init/action.cpp +++ b/init/action.cpp @@ -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 diff --git a/init/action.h b/init/action.h index 85630c4de..2a6f36a59 100644 --- a/init/action.h +++ b/init/action.h @@ -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 diff --git a/init/action_manager.cpp b/init/action_manager.cpp new file mode 100644 index 000000000..7e0359052 --- /dev/null +++ b/init/action_manager.cpp @@ -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 diff --git a/init/action_manager.h b/init/action_manager.h new file mode 100644 index 000000000..5f47a6db0 --- /dev/null +++ b/init/action_manager.h @@ -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 diff --git a/init/action_parser.h b/init/action_parser.h index 32403b6a6..b7f70743a 100644 --- a/init/action_parser.h +++ b/init/action_parser.h @@ -21,6 +21,7 @@ #include <vector> #include "action.h" +#include "action_manager.h" #include "parser.h" #include "subcontext.h" diff --git a/init/builtins.cpp b/init/builtins.cpp index be259c2e3..5d924b1ff 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -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" diff --git a/init/init.h b/init/init.h index ff7bdeb95..ecce5d789 100644 --- a/init/init.h +++ b/init/init.h @@ -21,6 +21,7 @@ #include <vector> #include "action.h" +#include "action_manager.h" #include "parser.h" #include "service.h" diff --git a/init/init_test.cpp b/init/init_test.cpp index d78aabd16..0f9635f81 100644 --- a/init/init_test.cpp +++ b/init/init_test.cpp @@ -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" diff --git a/init/reboot.cpp b/init/reboot.cpp index a88a42d74..242750a85 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp @@ -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" |