12d43be4eSopenharmony_ci/* 22d43be4eSopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 32d43be4eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 42d43be4eSopenharmony_ci * you may not use this file except in compliance with the License. 52d43be4eSopenharmony_ci * You may obtain a copy of the License at 62d43be4eSopenharmony_ci * 72d43be4eSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 82d43be4eSopenharmony_ci * 92d43be4eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 102d43be4eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 112d43be4eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 122d43be4eSopenharmony_ci * See the License for the specific language governing permissions and 132d43be4eSopenharmony_ci * limitations under the License. 142d43be4eSopenharmony_ci */ 152d43be4eSopenharmony_ci 162d43be4eSopenharmony_ci#ifndef STATE_MACHINE_H 172d43be4eSopenharmony_ci#define STATE_MACHINE_H 182d43be4eSopenharmony_ci 192d43be4eSopenharmony_ci#include <memory> 202d43be4eSopenharmony_ci#include <mutex> 212d43be4eSopenharmony_ci#include <utility> 222d43be4eSopenharmony_ci#include <vector> 232d43be4eSopenharmony_ci 242d43be4eSopenharmony_ci#include "cellular_data_event_code.h" 252d43be4eSopenharmony_ci#include "inner_event.h" 262d43be4eSopenharmony_ci#include "tel_event_handler.h" 272d43be4eSopenharmony_ci#include "telephony_log_wrapper.h" 282d43be4eSopenharmony_ci 292d43be4eSopenharmony_cinamespace OHOS { 302d43be4eSopenharmony_cinamespace Telephony { 312d43be4eSopenharmony_ciclass State : public RefBase { 322d43be4eSopenharmony_ci#define PROCESSED true 332d43be4eSopenharmony_ci#define NOT_PROCESSED false 342d43be4eSopenharmony_cipublic: 352d43be4eSopenharmony_ci explicit State(std::string &&name) : name_(std::move(name)) {} 362d43be4eSopenharmony_ci virtual ~State() = default; 372d43be4eSopenharmony_ci virtual void StateBegin() = 0; 382d43be4eSopenharmony_ci virtual void StateEnd() = 0; 392d43be4eSopenharmony_ci virtual bool StateProcess(const AppExecFwk::InnerEvent::Pointer &event) = 0; 402d43be4eSopenharmony_ci 412d43be4eSopenharmony_ci void SetParentState(sptr<State> &parent) 422d43be4eSopenharmony_ci { 432d43be4eSopenharmony_ci parent_ = parent; 442d43be4eSopenharmony_ci } 452d43be4eSopenharmony_ci 462d43be4eSopenharmony_ci std::string GetStateMachineName() const 472d43be4eSopenharmony_ci { 482d43be4eSopenharmony_ci return name_; 492d43be4eSopenharmony_ci } 502d43be4eSopenharmony_ci 512d43be4eSopenharmony_ciprotected: 522d43be4eSopenharmony_ci friend class StateMachineEventHandler; 532d43be4eSopenharmony_ci std::string name_; 542d43be4eSopenharmony_ci sptr<State> parent_; 552d43be4eSopenharmony_ci bool isActive_ = false; 562d43be4eSopenharmony_ci}; 572d43be4eSopenharmony_ci 582d43be4eSopenharmony_ciclass StateMachineEventHandler : public TelEventHandler { 592d43be4eSopenharmony_cipublic: 602d43be4eSopenharmony_ci explicit StateMachineEventHandler(const std::string &name) : TelEventHandler(name) {} 612d43be4eSopenharmony_ci ~StateMachineEventHandler() = default; 622d43be4eSopenharmony_ci 632d43be4eSopenharmony_ci virtual void SetOriginalState(sptr<State> &originalState) 642d43be4eSopenharmony_ci { 652d43be4eSopenharmony_ci originalState_ = originalState; 662d43be4eSopenharmony_ci } 672d43be4eSopenharmony_ci 682d43be4eSopenharmony_ci virtual void TransitionTo(sptr<State> &destState) 692d43be4eSopenharmony_ci { 702d43be4eSopenharmony_ci TELEPHONY_LOGI("State machine transition to %{public}s", destState->name_.c_str()); 712d43be4eSopenharmony_ci destState_ = destState; 722d43be4eSopenharmony_ci } 732d43be4eSopenharmony_ci 742d43be4eSopenharmony_ci virtual void Quit() 752d43be4eSopenharmony_ci { 762d43be4eSopenharmony_ci sptr<State> tmpState = curState_; 772d43be4eSopenharmony_ci while (tmpState != nullptr && tmpState->isActive_) { 782d43be4eSopenharmony_ci tmpState->StateEnd(); 792d43be4eSopenharmony_ci tmpState = tmpState->parent_; 802d43be4eSopenharmony_ci isQuit_ = true; 812d43be4eSopenharmony_ci } 822d43be4eSopenharmony_ci } 832d43be4eSopenharmony_ci 842d43be4eSopenharmony_ci // Only two-layer StateMachines are supported 852d43be4eSopenharmony_ci virtual void ProcessTransitions(const AppExecFwk::InnerEvent::Pointer &event) 862d43be4eSopenharmony_ci { 872d43be4eSopenharmony_ci if (curState_ != destState_) { 882d43be4eSopenharmony_ci TELEPHONY_LOGD("Begin process transitions"); 892d43be4eSopenharmony_ci if (curState_ != nullptr) { 902d43be4eSopenharmony_ci sptr<State> tmpState = curState_->parent_; 912d43be4eSopenharmony_ci while (tmpState != nullptr) { 922d43be4eSopenharmony_ci tmpState->StateEnd(); 932d43be4eSopenharmony_ci tmpState = tmpState->parent_; 942d43be4eSopenharmony_ci } 952d43be4eSopenharmony_ci curState_->StateEnd(); 962d43be4eSopenharmony_ci } 972d43be4eSopenharmony_ci if (destState_ != nullptr) { 982d43be4eSopenharmony_ci sptr<State> tmpState = destState_->parent_; 992d43be4eSopenharmony_ci while (tmpState != nullptr) { 1002d43be4eSopenharmony_ci tmpState->StateBegin(); 1012d43be4eSopenharmony_ci tmpState = tmpState->parent_; 1022d43be4eSopenharmony_ci } 1032d43be4eSopenharmony_ci destState_->StateBegin(); 1042d43be4eSopenharmony_ci } 1052d43be4eSopenharmony_ci curState_ = destState_; 1062d43be4eSopenharmony_ci SendDeferredEvent(); 1072d43be4eSopenharmony_ci } 1082d43be4eSopenharmony_ci } 1092d43be4eSopenharmony_ci 1102d43be4eSopenharmony_ci void DeferEvent(AppExecFwk::InnerEvent::Pointer &&event) 1112d43be4eSopenharmony_ci { 1122d43be4eSopenharmony_ci std::lock_guard<std::mutex> guard(mtx_); 1132d43be4eSopenharmony_ci deferEvents_.push_back(std::move(event)); 1142d43be4eSopenharmony_ci } 1152d43be4eSopenharmony_ci 1162d43be4eSopenharmony_ci virtual void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) 1172d43be4eSopenharmony_ci { 1182d43be4eSopenharmony_ci if (event == nullptr || isQuit_) { 1192d43be4eSopenharmony_ci TELEPHONY_LOGE("The event parameter is incorrect"); 1202d43be4eSopenharmony_ci return; 1212d43be4eSopenharmony_ci } 1222d43be4eSopenharmony_ci if (event->GetInnerEventId() == CellularDataEventCode::MSG_STATE_MACHINE_QUIT) { 1232d43be4eSopenharmony_ci TELEPHONY_LOGI("State machine exit"); 1242d43be4eSopenharmony_ci Quit(); 1252d43be4eSopenharmony_ci return; 1262d43be4eSopenharmony_ci } 1272d43be4eSopenharmony_ci if (event->GetInnerEventId() == CellularDataEventCode::MSG_STATE_MACHINE_INIT) { 1282d43be4eSopenharmony_ci destState_ = originalState_; 1292d43be4eSopenharmony_ci InitCmdEnter(originalState_); 1302d43be4eSopenharmony_ci } 1312d43be4eSopenharmony_ci ProcessMsg(event); 1322d43be4eSopenharmony_ci ProcessTransitions(event); 1332d43be4eSopenharmony_ci } 1342d43be4eSopenharmony_ci 1352d43be4eSopenharmony_ci virtual void ProcessMsg(const AppExecFwk::InnerEvent::Pointer &event) 1362d43be4eSopenharmony_ci { 1372d43be4eSopenharmony_ci sptr<State> tmpState = curState_; 1382d43be4eSopenharmony_ci TELEPHONY_LOGD("The event id: %{public}u", event->GetInnerEventId()); 1392d43be4eSopenharmony_ci while (tmpState != nullptr && !tmpState->StateProcess(event)) { 1402d43be4eSopenharmony_ci tmpState = tmpState->parent_; 1412d43be4eSopenharmony_ci } 1422d43be4eSopenharmony_ci } 1432d43be4eSopenharmony_ci 1442d43be4eSopenharmony_ciprivate: 1452d43be4eSopenharmony_ci void InitCmdEnter(const sptr<State> &state) 1462d43be4eSopenharmony_ci { 1472d43be4eSopenharmony_ci if (state == nullptr) { 1482d43be4eSopenharmony_ci TELEPHONY_LOGE("registerState_ is null"); 1492d43be4eSopenharmony_ci return; 1502d43be4eSopenharmony_ci } 1512d43be4eSopenharmony_ci if (state->parent_ != nullptr) { 1522d43be4eSopenharmony_ci InitCmdEnter(state->parent_); 1532d43be4eSopenharmony_ci } 1542d43be4eSopenharmony_ci TELEPHONY_LOGI("Initialize entry %{public}s", state->name_.c_str()); 1552d43be4eSopenharmony_ci state->StateBegin(); 1562d43be4eSopenharmony_ci curState_ = state; 1572d43be4eSopenharmony_ci } 1582d43be4eSopenharmony_ci 1592d43be4eSopenharmony_ci void SendDeferredEvent() 1602d43be4eSopenharmony_ci { 1612d43be4eSopenharmony_ci std::lock_guard<std::mutex> guard(mtx_); 1622d43be4eSopenharmony_ci if (deferEvents_.empty()) { 1632d43be4eSopenharmony_ci return; 1642d43be4eSopenharmony_ci } 1652d43be4eSopenharmony_ci for (size_t i = 0; i < deferEvents_.size(); ++i) { 1662d43be4eSopenharmony_ci AppExecFwk::InnerEvent::Pointer event = std::move(deferEvents_[i]); 1672d43be4eSopenharmony_ci SendImmediateEvent(event); 1682d43be4eSopenharmony_ci } 1692d43be4eSopenharmony_ci deferEvents_.clear(); 1702d43be4eSopenharmony_ci } 1712d43be4eSopenharmony_ci 1722d43be4eSopenharmony_ciprivate: 1732d43be4eSopenharmony_ci sptr<State> originalState_; 1742d43be4eSopenharmony_ci sptr<State> destState_; 1752d43be4eSopenharmony_ci sptr<State> curState_; 1762d43be4eSopenharmony_ci std::vector<AppExecFwk::InnerEvent::Pointer> deferEvents_; 1772d43be4eSopenharmony_ci std::mutex mtx_; 1782d43be4eSopenharmony_ci bool isQuit_ = false; 1792d43be4eSopenharmony_ci}; 1802d43be4eSopenharmony_ci 1812d43be4eSopenharmony_ciclass StateMachine { 1822d43be4eSopenharmony_cipublic: 1832d43be4eSopenharmony_ci explicit StateMachine(const std::string &name) 1842d43be4eSopenharmony_ci { 1852d43be4eSopenharmony_ci stateMachineEventHandler_ = std::make_shared<StateMachineEventHandler>(name); 1862d43be4eSopenharmony_ci if (stateMachineEventHandler_ == nullptr) { 1872d43be4eSopenharmony_ci TELEPHONY_LOGE("stateMachineEventHandler_ is null"); 1882d43be4eSopenharmony_ci return; 1892d43be4eSopenharmony_ci } 1902d43be4eSopenharmony_ci } 1912d43be4eSopenharmony_ci 1922d43be4eSopenharmony_ci virtual ~StateMachine() {} 1932d43be4eSopenharmony_ci 1942d43be4eSopenharmony_ci void Quit() 1952d43be4eSopenharmony_ci { 1962d43be4eSopenharmony_ci AppExecFwk::InnerEvent::Pointer event = 1972d43be4eSopenharmony_ci AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_STATE_MACHINE_QUIT); 1982d43be4eSopenharmony_ci if (stateMachineEventHandler_ == nullptr) { 1992d43be4eSopenharmony_ci TELEPHONY_LOGE("stateMachineEventHandler_ is null"); 2002d43be4eSopenharmony_ci return; 2012d43be4eSopenharmony_ci } 2022d43be4eSopenharmony_ci stateMachineEventHandler_->SendImmediateEvent(event); 2032d43be4eSopenharmony_ci } 2042d43be4eSopenharmony_ci 2052d43be4eSopenharmony_ci void Start() 2062d43be4eSopenharmony_ci { 2072d43be4eSopenharmony_ci if (stateMachineEventHandler_ == nullptr) { 2082d43be4eSopenharmony_ci TELEPHONY_LOGE("stateMachineEventHandler_ is null"); 2092d43be4eSopenharmony_ci return; 2102d43be4eSopenharmony_ci } 2112d43be4eSopenharmony_ci AppExecFwk::InnerEvent::Pointer event = 2122d43be4eSopenharmony_ci AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_STATE_MACHINE_INIT); 2132d43be4eSopenharmony_ci stateMachineEventHandler_->SendImmediateEvent(event); 2142d43be4eSopenharmony_ci } 2152d43be4eSopenharmony_ci 2162d43be4eSopenharmony_ci void SetOriginalState(sptr<State> &originalState) 2172d43be4eSopenharmony_ci { 2182d43be4eSopenharmony_ci if (originalState == nullptr) { 2192d43be4eSopenharmony_ci TELEPHONY_LOGE("originalState is null"); 2202d43be4eSopenharmony_ci return; 2212d43be4eSopenharmony_ci } 2222d43be4eSopenharmony_ci if (stateMachineEventHandler_ == nullptr) { 2232d43be4eSopenharmony_ci TELEPHONY_LOGE("stateMachineEventHandler_ is null"); 2242d43be4eSopenharmony_ci return; 2252d43be4eSopenharmony_ci } 2262d43be4eSopenharmony_ci stateMachineEventHandler_->SetOriginalState(originalState); 2272d43be4eSopenharmony_ci } 2282d43be4eSopenharmony_ci 2292d43be4eSopenharmony_ci void TransitionTo(sptr<State> &destState) 2302d43be4eSopenharmony_ci { 2312d43be4eSopenharmony_ci if (destState == nullptr) { 2322d43be4eSopenharmony_ci TELEPHONY_LOGE("destState is null"); 2332d43be4eSopenharmony_ci return; 2342d43be4eSopenharmony_ci } 2352d43be4eSopenharmony_ci if (stateMachineEventHandler_ == nullptr) { 2362d43be4eSopenharmony_ci TELEPHONY_LOGE("stateMachineEventHandler_ is null"); 2372d43be4eSopenharmony_ci return; 2382d43be4eSopenharmony_ci } 2392d43be4eSopenharmony_ci stateMachineEventHandler_->TransitionTo(destState); 2402d43be4eSopenharmony_ci } 2412d43be4eSopenharmony_ci 2422d43be4eSopenharmony_ci void DeferEvent(const AppExecFwk::InnerEvent::Pointer &&event) 2432d43be4eSopenharmony_ci { 2442d43be4eSopenharmony_ci if (stateMachineEventHandler_ == nullptr) { 2452d43be4eSopenharmony_ci TELEPHONY_LOGE("stateMachineEventHandler_ is null"); 2462d43be4eSopenharmony_ci return; 2472d43be4eSopenharmony_ci } 2482d43be4eSopenharmony_ci stateMachineEventHandler_->DeferEvent(std::move(const_cast<AppExecFwk::InnerEvent::Pointer &>(event))); 2492d43be4eSopenharmony_ci } 2502d43be4eSopenharmony_ci 2512d43be4eSopenharmony_ci void SendEvent(AppExecFwk::InnerEvent::Pointer &event) 2522d43be4eSopenharmony_ci { 2532d43be4eSopenharmony_ci if (stateMachineEventHandler_ == nullptr) { 2542d43be4eSopenharmony_ci TELEPHONY_LOGE("stateMachineEventHandler_ is null"); 2552d43be4eSopenharmony_ci return; 2562d43be4eSopenharmony_ci } 2572d43be4eSopenharmony_ci if (event == nullptr) { 2582d43be4eSopenharmony_ci TELEPHONY_LOGE("event is null"); 2592d43be4eSopenharmony_ci return; 2602d43be4eSopenharmony_ci } 2612d43be4eSopenharmony_ci TELEPHONY_LOGD("State machine send event id %{public}u ", event->GetInnerEventId()); 2622d43be4eSopenharmony_ci stateMachineEventHandler_->SendEvent(event); 2632d43be4eSopenharmony_ci } 2642d43be4eSopenharmony_ci 2652d43be4eSopenharmony_ciprotected: 2662d43be4eSopenharmony_ci std::shared_ptr<StateMachineEventHandler> stateMachineEventHandler_; 2672d43be4eSopenharmony_ci}; 2682d43be4eSopenharmony_ci} // namespace Telephony 2692d43be4eSopenharmony_ci} // namespace OHOS 2702d43be4eSopenharmony_ci#endif // STATE_MACHINE_H 271