• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "mc_connect_manager.h"
17 
18 #include <chrono>
19 #include <functional>
20 #include <thread>
21 #include <unistd.h>
22 
23 #include "event_runner.h"
24 #include "mechbody_controller_service.h"
25 
26 namespace OHOS {
27 namespace MechBodyController {
GetInstance()28 MechConnectManager& MechConnectManager::GetInstance()
29 {
30     static auto instance = new MechConnectManager();
31     return *instance;
32 }
33 
34 namespace {
35 const std::string TAG = "MechConnectManager";
36 }
37 
Init()38 void MechConnectManager::Init()
39 {
40     HILOGI("called");
41     auto runner = AppExecFwk::EventRunner::Create("dmsDnetwork");
42     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
43 }
44 
UnInit()45 void MechConnectManager::UnInit()
46 {
47     HILOGI("called");
48     if (eventHandler_ != nullptr) {
49         eventHandler_->GetEventRunner()->Stop();
50     } else {
51         HILOGE("eventHandler_ is nullptr");
52     }
53 }
54 
NotifyMechConnect(MechInfo & mechInfo)55 int32_t MechConnectManager::NotifyMechConnect(MechInfo& mechInfo)
56 {
57     MechBodyControllerService::GetInstance().OnDeviceConnected(mechInfo.mechId);
58     auto connectNotifyTask = [this, mechInfo]() {
59         std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
60         for (auto& listener : listenerSet_) {
61             if (listener != nullptr) {
62                 listener->OnMechConnect(mechInfo);
63             }
64         }
65     };
66     if (eventHandler_ == nullptr || !eventHandler_->PostTask(connectNotifyTask)) {
67         HILOGE("post task failed");
68         return ERR_OK;
69     }
70     return ERR_OK;
71 }
72 
NotifyMechDisconnect(const MechInfo & mechInfo)73 int32_t MechConnectManager::NotifyMechDisconnect(const MechInfo& mechInfo)
74 {
75     HILOGI("called, mechId: %{public}d.", mechInfo.mechId);
76     {
77         std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
78         auto it = mechInfos_.find(mechInfo);
79         if (it != mechInfos_.end()) {
80             mechInfos_.erase(it);
81             MechBodyControllerService::GetInstance().OnDeviceDisconnected(mechInfo.mechId);
82         }
83     }
84     auto offlineNotifyTask = [this, mechInfo]() {
85         std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
86         for (auto& listener : listenerSet_) {
87             if (listener != nullptr) {
88                 listener->OnMechDisconnect(mechInfo);
89             }
90         }
91     };
92     if (eventHandler_ == nullptr || !eventHandler_->PostTask(offlineNotifyTask)) {
93         HILOGE("post task failed");
94         return ERR_OK;
95     }
96     return ERR_OK;
97 }
98 
AddDeviceChangeListener(const std::shared_ptr<IMechConnectListener> & listener)99 int32_t MechConnectManager::AddDeviceChangeListener(const std::shared_ptr<IMechConnectListener>& listener)
100 {
101     HILOGI("called");
102     if (listener == nullptr) {
103         HILOGI("listener is nullptr.");
104         return INVALID_PARAMETERS_ERR;
105     }
106     std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
107     auto result = listenerSet_.insert(listener);
108     if (!result.second) {
109         HILOGI("listener is already.");
110     }
111     if (listenerSet_.find(listener) == listenerSet_.end()) {
112         HILOGI("error.");
113         return INVALID_PARAMETERS_ERR;
114     }
115     return ERR_OK;
116 }
117 
RemoveDeviceChangeListener(const std::shared_ptr<IMechConnectListener> & listener)118 int32_t MechConnectManager::RemoveDeviceChangeListener(const std::shared_ptr<IMechConnectListener>& listener)
119 {
120     HILOGI("called");
121     if (listener == nullptr) {
122         HILOGI("listener is nullptr.");
123         return INVALID_PARAMETERS_ERR;
124     }
125     {
126         std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
127         auto it = listenerSet_.find(listener);
128         if (it == listenerSet_.end()) {
129             HILOGI("error.");
130             return INVALID_PARAMETERS_ERR;
131         }
132         listenerSet_.erase(listener);
133         if (listenerSet_.size() > 0) {
134             return ERR_OK;
135         }
136     }
137     HILOGI("remove ok");
138     return ERR_OK;
139 }
140 
GetMechBasicInfo(int32_t mechId,MechInfo & mechInfo)141 bool MechConnectManager::GetMechBasicInfo(int32_t mechId, MechInfo& mechInfo)
142 {
143     HILOGI("called, mechId: %{public}d", mechId);
144     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
145     auto it = std::find_if(mechInfos_.begin(), mechInfos_.end(), [mechId](const MechInfo& mechInfo) {
146         return mechInfo.mechId == mechId;
147     });
148     if (it == mechInfos_.end()) {
149         HILOGE("not found");
150         return false;
151     }
152     HILOGI("found");
153     mechInfo = *it;
154     return true;
155 }
156 
GetConnectMechList(std::set<MechInfo> & mechInfos)157 bool MechConnectManager::GetConnectMechList(std::set<MechInfo>& mechInfos)
158 {
159     HILOGI("called");
160     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
161     if (mechInfos_.empty()) {
162         HILOGE("list is empty");
163         return false;
164     }
165     mechInfos = mechInfos_;
166     return true;
167 }
168 
NotifyMechState(int32_t mechId,bool isAttached)169 bool MechConnectManager::NotifyMechState(int32_t mechId, bool isAttached)
170 {
171     HILOGI("called, mechId: %{public}d. isAttached %{public}d", mechId, isAttached);
172     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
173     auto it = std::find_if(mechInfos_.begin(), mechInfos_.end(),
174         [&](const MechInfo& mechInfo) { return mechInfo.mechId == mechId; });
175     if (it == mechInfos_.end()) {
176         HILOGE("can not find this mechInfo");
177         return false;
178     }
179     MechInfo newMechInfo = *it;
180     newMechInfo.state = isAttached ? AttachmentState::ATTACHED : AttachmentState::DETACHED;
181     mechInfos_.erase(it);
182     mechInfos_.insert(newMechInfo);
183 
184     if (!isAttached) {
185         auto disconnectTask = [this, newMechInfo]() mutable {
186             BleSendManager::GetInstance().MechbodyDisConnect(newMechInfo);
187         };
188         if (eventHandler_ == nullptr || !eventHandler_->PostTask(disconnectTask, "disconnect")) {
189             HILOGE("MECHBODY_EXEC_CONNECT post task failed");
190             return ERR_OK;
191         }
192     }
193     return true;
194 }
195 
GetMechState(int32_t mechId)196 bool MechConnectManager::GetMechState(int32_t mechId)
197 {
198     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
199     auto it = std::find_if(mechInfos_.begin(), mechInfos_.end(), [mechId](const MechInfo& mechInfo) {
200         return mechInfo.mechId == mechId;
201     });
202     if (it == mechInfos_.end()) {
203         HILOGE("mechId: %{public}d not found", mechId);
204         return false;
205     }
206     HILOGD("mechId: %{public}d found", mechId);
207     MechInfo mechInfo = *it;
208     return mechInfo.state == AttachmentState::ATTACHED ? true : false;
209 }
210 
UpdateBleStatus(bool isBLEActive)211 bool MechConnectManager::UpdateBleStatus(bool isBLEActive)
212 {
213     HILOGI("called");
214     isBLEActive_.store(isBLEActive);
215     return true;
216 }
217 
GetLocalDeviceBleStatus()218 bool MechConnectManager::GetLocalDeviceBleStatus()
219 {
220     HILOGD("called");
221     return isBLEActive_.load();
222 }
223 
IsConnect()224 bool MechConnectManager::IsConnect()
225 {
226     HILOGI("called");
227     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
228     if (mechInfos_.empty() || mechInfos_.size() == 0) {
229         HILOGW("list is empty");
230         return false;
231     }
232     return true;
233 }
234 
AddMechInfo(MechInfo & mechInfo)235 int32_t MechConnectManager::AddMechInfo(MechInfo &mechInfo)
236 {
237     {
238         HILOGI("MECHBODY_EXEC_CONNECT mechInfo: %{public}s", mechInfo.ToString().c_str());
239         std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
240         while (mechInfos_.count(mechInfo) != 0) {
241             mechInfo.mechId = (mechInfo.mechId + 1) % INT32_MAX;
242         }
243         mechInfos_.insert(mechInfo);
244     }
245     return ERR_OK;
246 }
247 
248 
GetMechInfo(std::string & mac,MechInfo & mechInfo)249 int32_t MechConnectManager::GetMechInfo(std::string &mac, MechInfo &mechInfo)
250 {
251     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
252     for (auto &info: mechInfos_) {
253         if (info.mac == mac) {
254             mechInfo = info;
255             HILOGI("MECHBODY_EXEC_CONNECT mechInfo: %{public}s", info.ToString().c_str());
256             return ERR_OK;
257         }
258     }
259     return MECH_INFO_NOT_FOUND;
260 }
261 
SetMechanicGattState(std::string & mac,bool state)262 int32_t MechConnectManager::SetMechanicGattState(std::string &mac, bool state)
263 {
264     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
265     for (const auto& info : mechInfos_) {
266         if (info.mac == mac) {
267             const_cast<MechInfo&>(info).gattCoonectState = state;
268             HILOGI("MECHBODY_EXEC_CONNECT mechInfo: %{public}s", info.ToString().c_str());
269             return ERR_OK;
270         }
271     }
272     return MECH_INFO_NOT_FOUND;
273 }
GetMechanicGattState(std::string & mac,bool & state)274 int32_t MechConnectManager::GetMechanicGattState(std::string &mac, bool &state)
275 {
276     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
277     for (auto &info: mechInfos_) {
278         if (info.mac == mac) {
279             state = info.gattCoonectState;
280             HILOGI("MECHBODY_EXEC_CONNECT mechInfo: %{public}s", info.ToString().c_str());
281             return ERR_OK;
282         }
283     }
284     return MECH_INFO_NOT_FOUND;
285 }
286 
SetMechanicPairState(std::string & mac,bool state)287 int32_t MechConnectManager::SetMechanicPairState(std::string &mac, bool state)
288 {
289     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
290     for (const auto& info : mechInfos_) {
291         if (info.mac == mac) {
292             const_cast<MechInfo&>(info).pairState = state;
293             HILOGI("MECHBODY_EXEC_CONNECT mechInfo: %{public}s", info.ToString().c_str());
294             return ERR_OK;
295         }
296     }
297     return MECH_INFO_NOT_FOUND;
298 }
299 
GetMechanicPairState(std::string & mac,bool & state)300 int32_t MechConnectManager::GetMechanicPairState(std::string &mac, bool &state)
301 {
302     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
303     for (auto &info: mechInfos_) {
304         if (info.mac == mac) {
305             state = info.pairState;
306             HILOGI("MECHBODY_EXEC_CONNECT mechInfo: %{public}s", info.ToString().c_str());
307             return ERR_OK;
308         }
309     }
310     return MECH_INFO_NOT_FOUND;
311 }
312 
SetMechanicHidState(std::string & mac,bool state)313 int32_t MechConnectManager::SetMechanicHidState(std::string &mac, bool state)
314 {
315     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
316     for (const auto& info : mechInfos_) {
317         if (info.mac == mac) {
318             const_cast<MechInfo&>(info).hidState = state;
319             HILOGI("MECHBODY_EXEC_CONNECT mechInfo: %{public}s", info.ToString().c_str());
320             return ERR_OK;
321         }
322     }
323     return MECH_INFO_NOT_FOUND;
324 }
325 
GetMechanicHidState(std::string & mac,bool & state)326 int32_t MechConnectManager::GetMechanicHidState(std::string &mac, bool &state)
327 {
328     std::lock_guard<std::mutex> autoLock(mechInfosMutex_);
329     for (auto &info: mechInfos_) {
330         if (info.mac == mac) {
331             state = info.hidState;
332             HILOGI("MECHBODY_EXEC_CONNECT mechInfo: %{public}s", info.ToString().c_str());
333             return ERR_OK;
334         }
335     }
336     return MECH_INFO_NOT_FOUND;
337 }
338 } // namespace MechBodyController
339 } // namespace OHOS
340