2 * Copyright 2018 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <base/logging.h>
29 * State machine used by Bluetooth native stack.
33 enum { kStateInvalid = -1 };
36 * A class to represent the state in the State Machine.
39 friend class StateMachine;
45 * @param sm the State Machine to use
46 * @param state_id the unique State ID. It should be a non-negative number.
48 State(StateMachine& sm, int state_id) : sm_(sm), state_id_(state_id) {}
50 virtual ~State() = default;
54 * TODO: The arguments are wrong - used for backward compatibility.
55 * Will be replaced later.
57 * @param event the event type
58 * @param p_data the event data
59 * @return true if the processing was completed, otherwise false
61 virtual bool ProcessEvent(uint32_t event, void* p_data) = 0;
66 * @return the State ID
68 int StateId() const { return state_id_; }
72 * Called when a state is entered.
74 virtual void OnEnter() {}
77 * Called when a state is exited.
79 virtual void OnExit() {}
82 * Transition the State Machine to a new state.
84 * @param dest_state_id the state ID to transition to. It must be one
85 * of the unique state IDs when the corresponding state was created.
87 void TransitionTo(int dest_state_id) { sm_.TransitionTo(dest_state_id); }
90 * Transition the State Machine to a new state.
92 * @param dest_state the state to transition to. It cannot be nullptr.
94 void TransitionTo(StateMachine::State* dest_state) {
95 sm_.TransitionTo(dest_state);
104 : initial_state_(nullptr),
105 previous_state_(nullptr),
106 current_state_(nullptr) {}
108 for (auto& kv : states_) delete kv.second;
112 * Start the State Machine operation.
114 void Start() { TransitionTo(initial_state_); }
117 * Quit the State Machine operation.
119 void Quit() { previous_state_ = current_state_ = nullptr; }
122 * Get the current State ID.
124 * @return the current State ID
126 int StateId() const {
127 if (current_state_ != nullptr) {
128 return current_state_->StateId();
130 return kStateInvalid;
134 * Get the previous current State ID.
136 * @return the previous State ID
138 int PreviousStateId() const {
139 if (previous_state_ != nullptr) {
140 return previous_state_->StateId();
142 return kStateInvalid;
147 * TODO: The arguments are wrong - used for backward compatibility.
148 * Will be replaced later.
150 * @param event the event type
151 * @param p_data the event data
152 * @return true if the processing was completed, otherwise false
154 bool ProcessEvent(uint32_t event, void* p_data) {
155 if (current_state_ == nullptr) return false;
156 return current_state_->ProcessEvent(event, p_data);
160 * Transition the State Machine to a new state.
162 * @param dest_state_id the state ID to transition to. It must be one
163 * of the unique state IDs when the corresponding state was created.
165 void TransitionTo(int dest_state_id) {
166 auto it = states_.find(dest_state_id);
168 CHECK(it != states_.end()) << "Unknown State ID: " << dest_state_id;
169 State* dest_state = it->second;
170 TransitionTo(dest_state);
174 * Transition the State Machine to a new state.
176 * @param dest_state the state to transition to. It cannot be nullptr.
178 void TransitionTo(StateMachine::State* dest_state) {
179 if (current_state_ != nullptr) {
180 current_state_->OnExit();
182 previous_state_ = current_state_;
183 current_state_ = dest_state;
184 current_state_->OnEnter();
188 * Add a state to the State Machine.
189 * The state machine takes ownership on the state - i.e., the state will
190 * be deleted by the State Machine itself.
192 * @param state the state to add
194 void AddState(State* state) {
195 states_.insert(std::make_pair(state->StateId(), state));
199 * Set the initial state of the State Machine.
201 * @param initial_state the initial state
203 void SetInitialState(State* initial_state) { initial_state_ = initial_state; }
206 State* initial_state_;
207 State* previous_state_;
208 State* current_state_;
209 std::map<int, State*> states_;
212 } // namespace common
214 } // namespace bluetooth