blob: ebca762ca0acc2cb00682abd5198a27fd9b9d913 [file] [log] [blame]
Tom Cherry7fd3bc22018-02-13 15:36:14 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "action_manager.h"
18
19#include <android-base/logging.h>
20
21namespace android {
22namespace init {
23
24ActionManager::ActionManager() : current_command_(0) {}
25
Tom Cherry4772f1d2019-07-30 09:34:41 -070026size_t ActionManager::CheckAllCommands() {
27 size_t failures = 0;
28 for (const auto& action : actions_) {
29 failures += action->CheckAllCommands();
30 }
31 return failures;
32}
33
Tom Cherry7fd3bc22018-02-13 15:36:14 -080034ActionManager& ActionManager::GetInstance() {
35 static ActionManager instance;
36 return instance;
37}
38
39void ActionManager::AddAction(std::unique_ptr<Action> action) {
40 actions_.emplace_back(std::move(action));
41}
42
43void ActionManager::QueueEventTrigger(const std::string& trigger) {
44 event_queue_.emplace(trigger);
45}
46
47void ActionManager::QueuePropertyChange(const std::string& name, const std::string& value) {
48 event_queue_.emplace(std::make_pair(name, value));
49}
50
51void ActionManager::QueueAllPropertyActions() {
52 QueuePropertyChange("", "");
53}
54
55void ActionManager::QueueBuiltinAction(BuiltinFunction func, const std::string& name) {
Tom Cherry9cbf5702018-02-13 16:24:51 -080056 auto action = std::make_unique<Action>(true, nullptr, "<Builtin Action>", 0, name,
57 std::map<std::string, std::string>{});
Tom Cherry7c1d87e2019-07-10 11:18:24 -070058 action->AddCommand(std::move(func), {name}, 0);
Tom Cherry7fd3bc22018-02-13 15:36:14 -080059
60 event_queue_.emplace(action.get());
61 actions_.emplace_back(std::move(action));
62}
63
64void ActionManager::ExecuteOneCommand() {
65 // Loop through the event queue until we have an action to execute
66 while (current_executing_actions_.empty() && !event_queue_.empty()) {
67 for (const auto& action : actions_) {
68 if (std::visit([&action](const auto& event) { return action->CheckEvent(event); },
69 event_queue_.front())) {
70 current_executing_actions_.emplace(action.get());
71 }
72 }
73 event_queue_.pop();
74 }
75
76 if (current_executing_actions_.empty()) {
77 return;
78 }
79
80 auto action = current_executing_actions_.front();
81
82 if (current_command_ == 0) {
83 std::string trigger_name = action->BuildTriggersString();
84 LOG(INFO) << "processing action (" << trigger_name << ") from (" << action->filename()
85 << ":" << action->line() << ")";
86 }
87
88 action->ExecuteOneCommand(current_command_);
89
90 // If this was the last command in the current action, then remove
91 // the action from the executing list.
92 // If this action was oneshot, then also remove it from actions_.
93 ++current_command_;
94 if (current_command_ == action->NumCommands()) {
95 current_executing_actions_.pop();
96 current_command_ = 0;
97 if (action->oneshot()) {
98 auto eraser = [&action](std::unique_ptr<Action>& a) { return a.get() == action; };
Tom Cherry247ffbf2019-07-08 15:09:36 -070099 actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser),
100 actions_.end());
Tom Cherry7fd3bc22018-02-13 15:36:14 -0800101 }
102 }
103}
104
105bool ActionManager::HasMoreCommands() const {
106 return !current_executing_actions_.empty() || !event_queue_.empty();
107}
108
109void ActionManager::DumpState() const {
110 for (const auto& a : actions_) {
111 a->DumpState();
112 }
113}
114
115void ActionManager::ClearQueue() {
116 // We are shutting down so don't claim the oneshot builtin actions back
117 current_executing_actions_ = {};
118 event_queue_ = {};
119 current_command_ = 0;
120}
121
122} // namespace init
123} // namespace android