1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "adapter_state_machine.h"
17 
18 #include "log.h"
19 
20 #include "adapter_manager.h"
21 #include "power_manager.h"
22 #include "profile_service_manager.h"
23 
24 namespace OHOS {
25 namespace bluetooth {
26 const int ENABLE_DISABLE_TIMEOUT_TIME = 70000;
27 
Init(IAdapter & adapter)28 void AdapterStateMachine::Init(IAdapter &adapter)
29 {
30     std::unique_ptr<utility::StateMachine::State> turningOn = std::make_unique<AdapterTurningOnState>(*this, adapter);
31     Move(turningOn);
32     std::unique_ptr<utility::StateMachine::State> turnOn = std::make_unique<AdapterTurnOnState>(*this, adapter);
33     Move(turnOn);
34     std::unique_ptr<utility::StateMachine::State> turningOff = std::make_unique<AdapterTurningOffState>(*this, adapter);
35     Move(turningOff);
36     std::unique_ptr<utility::StateMachine::State> turnOff = std::make_unique<AdapterTurnOffState>(*this, adapter);
37     Move(turnOff);
38     InitState(TURN_OFF_STATE);
39 }
40 
GetDispatch() const41 utility::Dispatcher &AdapterStateMachine::GetDispatch() const
42 {
43     return dispatch_;
44 }
45 
Entry()46 void AdapterTurnOffState::Entry()
47 {
48     BTTransport transport =
49         (adapter_.GetContext()->Name() == ADAPTER_NAME_CLASSIC) ? BTTransport::ADAPTER_BREDR : BTTransport::ADAPTER_BLE;
50     AdapterManager::GetInstance()->OnAdapterStateChange(transport, BTStateID::STATE_TURN_OFF);
51 }
52 
Dispatch(const utility::Message & msg)53 bool AdapterTurnOffState::Dispatch(const utility::Message &msg)
54 {
55     switch (msg.what_) {
56         case AdapterStateMachine::MSG_USER_ENABLE_REQ:
57             Transition(TURNING_ON_STATE);
58             return true;
59         default:
60             return false;
61     }
62 }
63 
AdapterTurningOnState(AdapterStateMachine & stateMachine,IAdapter & adapter)64 AdapterTurningOnState::AdapterTurningOnState(AdapterStateMachine &stateMachine, IAdapter &adapter)
65     : AdapterState(TURNING_ON_STATE, stateMachine, adapter)
66 {
67     adapterTimer_ = std::make_unique<utility::Timer>([&]() -> void {
68         stateMachine.GetDispatch().PostTask(std::bind(
69             &utility::StateMachine::ProcessMessage, &stateMachine, AdapterStateMachine::MSG_ADAPTER_ENABLE_TIME_OUT));
70     });
71     profileTimer_ = std::make_unique<utility::Timer>([&]() -> void {
72         stateMachine.GetDispatch().PostTask(std::bind(
73             &utility::StateMachine::ProcessMessage, &stateMachine, AdapterStateMachine::MSG_PROFILE_ENABLE_TIME_OUT));
74     });
75 }
76 
Entry()77 void AdapterTurningOnState::Entry()
78 {
79     BTTransport transport =
80         (adapter_.GetContext()->Name() == ADAPTER_NAME_CLASSIC) ? BTTransport::ADAPTER_BREDR : BTTransport::ADAPTER_BLE;
81     AdapterManager::GetInstance()->OnAdapterStateChange(transport, BTStateID::STATE_TURNING_ON);
82     LOG_DEBUG("AdapterStateMachine::Timer enable adapter start transport is %{public}d", transport);
83     adapterTimer_->Start(ENABLE_DISABLE_TIMEOUT_TIME, false);
84     adapter_.GetContext()->Enable();
85 }
86 
Dispatch(const utility::Message & msg)87 bool AdapterTurningOnState::Dispatch(const utility::Message &msg)
88 {
89     BTTransport transport =
90         (adapter_.GetContext()->Name() == ADAPTER_NAME_CLASSIC) ? BTTransport::ADAPTER_BREDR : BTTransport::ADAPTER_BLE;
91     switch (msg.what_) {
92         case AdapterStateMachine::MSG_ADAPTER_ENABLE_CMP:
93             LOG_DEBUG("AdapterStateMachine::Timer enable adapter stop transport is %{public}d", transport);
94             adapterTimer_->Stop();
95             if (msg.arg1_) {
96                 LOG_DEBUG("AdapterStateMachine::Timer enable profile start transport is %{public}d", transport);
97                 if (transport == BTTransport::ADAPTER_BREDR) {
98                     IPowerManager::GetInstance().Enable();
99                 }
100                 profileTimer_->Start(ENABLE_DISABLE_TIMEOUT_TIME, false);
101                 ProfileServiceManager::GetInstance()->Enable(transport);
102             } else {
103                 Transition(TURNING_OFF_STATE);
104             }
105             break;
106         case AdapterStateMachine::MSG_PROFILE_ENABLE_CMP:
107             LOG_DEBUG("AdapterStateMachine::Timer enable profile stop transport is %{public}d", transport);
108             profileTimer_->Stop();
109             if (msg.arg1_) {
110                 Transition(TURN_ON_STATE);
111             } else {
112                 ProfileServiceManager::GetInstance()->OnAllEnabled(transport);
113                 Transition(TURNING_OFF_STATE);
114             }
115             break;
116         case AdapterStateMachine::MSG_ADAPTER_ENABLE_TIME_OUT:
117             LOG_DEBUG("AdapterStateMachine::Timer enable timer out transport is %{public}d", transport);
118             AdapterManager::GetInstance()->Reset();
119             adapterStateMachine_.GetDispatch().PostTask(
120                 std::bind(&AdapterTurningOnState::Transition, this, TURNING_OFF_STATE));
121             break;
122         case AdapterStateMachine::MSG_PROFILE_ENABLE_TIME_OUT:
123             LOG_DEBUG("AdapterStateMachine::Timer enable timer out transport is %{public}d", transport);
124             AdapterManager::GetInstance()->Reset();
125             ProfileServiceManager::GetInstance()->OnAllEnabled(transport);
126             adapterStateMachine_.GetDispatch().PostTask(
127                 std::bind(&AdapterTurningOnState::Transition, this, TURNING_OFF_STATE));
128             break;
129         default:
130             return false;
131     }
132     return true;
133 }
134 
Entry()135 void AdapterTurnOnState::Entry()
136 {
137     BTTransport transport =
138         (adapter_.GetContext()->Name() == ADAPTER_NAME_CLASSIC) ? BTTransport::ADAPTER_BREDR : BTTransport::ADAPTER_BLE;
139     AdapterManager::GetInstance()->OnAdapterStateChange(transport, BTStateID::STATE_TURN_ON);
140     adapter_.GetContext()->PostEnable();
141 }
142 
Dispatch(const utility::Message & msg)143 bool AdapterTurnOnState::Dispatch(const utility::Message &msg)
144 {
145     switch (msg.what_) {
146         case AdapterStateMachine::MSG_USER_DISABLE_REQ:
147             Transition(TURNING_OFF_STATE);
148             return true;
149         default:
150             return false;
151     }
152 }
153 
AdapterTurningOffState(AdapterStateMachine & stateMachine,IAdapter & adapter)154 AdapterTurningOffState::AdapterTurningOffState(AdapterStateMachine &stateMachine, IAdapter &adapter)
155     : AdapterState(TURNING_OFF_STATE, stateMachine, adapter)
156 {
157     adapterTimer_ = std::make_unique<utility::Timer>([&]() -> void {
158         stateMachine.GetDispatch().PostTask(std::bind(
159             &utility::StateMachine::ProcessMessage, &stateMachine, AdapterStateMachine::MSG_ADAPTER_DISABLE_TIME_OUT));
160     });
161     profileTimer_ = std::make_unique<utility::Timer>([&]() -> void {
162         stateMachine.GetDispatch().PostTask(std::bind(
163             &utility::StateMachine::ProcessMessage, &stateMachine, AdapterStateMachine::MSG_PROFILE_DISABLE_TIME_OUT));
164     });
165 }
166 
Entry()167 void AdapterTurningOffState::Entry()
168 {
169     BTTransport transport =
170         (adapter_.GetContext()->Name() == ADAPTER_NAME_CLASSIC) ? BTTransport::ADAPTER_BREDR : BTTransport::ADAPTER_BLE;
171     AdapterManager::GetInstance()->OnAdapterStateChange(transport, BTStateID::STATE_TURNING_OFF);
172     LOG_DEBUG("AdapterStateMachine::Timer disable profile start transport is %{public}d", transport);
173     profileTimer_->Start(ENABLE_DISABLE_TIMEOUT_TIME, false);
174     ProfileServiceManager::GetInstance()->Disable(transport);
175 }
176 
Dispatch(const utility::Message & msg)177 bool AdapterTurningOffState::Dispatch(const utility::Message &msg)
178 {
179     BTTransport transport =
180         (adapter_.GetContext()->Name() == ADAPTER_NAME_CLASSIC) ? BTTransport::ADAPTER_BREDR : BTTransport::ADAPTER_BLE;
181     switch (msg.what_) {
182         case AdapterStateMachine::MSG_PROFILE_DISABLE_CMP:
183             LOG_DEBUG("AdapterStateMachine::Timer disable profile stop transport is %{public}d", transport);
184             profileTimer_->Stop();
185             LOG_DEBUG("AdapterStateMachine::Timer disable adapter Start transport is %{public}d", transport);
186             adapterTimer_->Start(ENABLE_DISABLE_TIMEOUT_TIME, false);
187             if (transport == BTTransport::ADAPTER_BREDR) {
188                 IPowerManager::GetInstance().Disable();
189             }
190             adapter_.GetContext()->Disable();
191             break;
192         case AdapterStateMachine::MSG_ADAPTER_DISABLE_CMP:
193             LOG_DEBUG("AdapterStateMachine::Timer disable adapter stop transport is %{public}d", transport);
194             adapterTimer_->Stop();
195             Transition(TURN_OFF_STATE);
196             break;
197         case AdapterStateMachine::MSG_PROFILE_DISABLE_TIME_OUT:
198             LOG_DEBUG("AdapterStateMachine::Timer disable profile time out transport is %{public}d", transport);
199             ProfileServiceManager::GetInstance()->OnAllDisabled(transport);
200             adapterTimer_->Start(ENABLE_DISABLE_TIMEOUT_TIME, false);
201             adapter_.GetContext()->Disable();
202             AdapterManager::GetInstance()->Reset();
203             break;
204         case AdapterStateMachine::MSG_ADAPTER_DISABLE_TIME_OUT:
205             LOG_DEBUG("AdapterStateMachine::Timer disable adapter time out transport is %{public}d", transport);
206             AdapterManager::GetInstance()->Reset();
207             adapterStateMachine_.GetDispatch().PostTask(
208                 std::bind(&AdapterTurningOffState::Transition, this, TURN_OFF_STATE));
209             break;
210         default:
211             return false;
212     }
213     return true;
214 }
215 }  // namespace bluetooth
216 }  // namespace OHOS