1 /*
2 * Copyright (c) 2022-2023 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 "coordination_manager_impl.h"
17
18 #include "devicestatus_client.h"
19 #include "devicestatus_define.h"
20 #include "include/util.h"
21
22 #undef LOG_TAG
23 #define LOG_TAG "CoordinationManagerImpl"
24
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28
RegisterCoordinationListener(CoordinationListenerPtr listener,bool isCompatible)29 int32_t CoordinationManagerImpl::RegisterCoordinationListener(CoordinationListenerPtr listener, bool isCompatible)
30 {
31 CALL_DEBUG_ENTER;
32 CHKPR(listener, RET_ERR);
33 std::lock_guard<std::mutex> guard(mtx_);
34 for (const auto &item : devCoordinationListener_) {
35 if (item == listener) {
36 FI_HILOGW("The listener already exists");
37 return RET_ERR;
38 }
39 }
40 if (!isListeningProcess_) {
41 FI_HILOGI("Start monitoring");
42 int32_t ret = DeviceStatusClient::GetInstance().RegisterCoordinationListener(isCompatible);
43 if (ret != RET_OK) {
44 FI_HILOGE("Failed to register, ret:%{public}d", ret);
45 return ret;
46 }
47 isListeningProcess_ = true;
48 }
49 devCoordinationListener_.push_back(listener);
50 return RET_OK;
51 }
52
UnregisterCoordinationListener(CoordinationListenerPtr listener,bool isCompatible)53 int32_t CoordinationManagerImpl::UnregisterCoordinationListener(
54 CoordinationListenerPtr listener, bool isCompatible)
55 {
56 CALL_DEBUG_ENTER;
57 std::lock_guard<std::mutex> guard(mtx_);
58 if (listener == nullptr) {
59 devCoordinationListener_.clear();
60 goto LISTENER_LABEL;
61 }
62 for (auto it = devCoordinationListener_.begin(); it != devCoordinationListener_.end(); ++it) {
63 if (*it == listener) {
64 devCoordinationListener_.erase(it);
65 goto LISTENER_LABEL;
66 }
67 }
68
69 LISTENER_LABEL:
70 if (isListeningProcess_ && devCoordinationListener_.empty()) {
71 isListeningProcess_ = false;
72 return DeviceStatusClient::GetInstance().UnregisterCoordinationListener(isCompatible);
73 }
74 return RET_OK;
75 }
76
PrepareCoordination(FuncCoordinationMessage callback,bool isCompatible)77 int32_t CoordinationManagerImpl::PrepareCoordination(FuncCoordinationMessage callback, bool isCompatible)
78 {
79 CALL_DEBUG_ENTER;
80 std::lock_guard<std::mutex> guard(mtx_);
81 prepareCooCallback_ = callback;
82 isPrepareCooIsCompatible_ = isCompatible;
83 SetMessageCallback(CallbackMessageId::PREPARE, callback);
84 int32_t userData = static_cast<int32_t> (CallbackMessageId::PREPARE);
85 int32_t ret = DeviceStatusClient::GetInstance().PrepareCoordination(userData, isCompatible);
86 if (ret != RET_OK) {
87 FI_HILOGE("Prepare coordination failed");
88 return ret;
89 }
90 return RET_OK;
91 }
92
UnprepareCoordination(FuncCoordinationMessage callback,bool isCompatible)93 int32_t CoordinationManagerImpl::UnprepareCoordination(FuncCoordinationMessage callback, bool isCompatible)
94 {
95 CALL_DEBUG_ENTER;
96 std::lock_guard<std::mutex> guard(mtx_);
97 SetMessageCallback(CallbackMessageId::UNPREPARE, callback);
98 int32_t userData = static_cast<int32_t> (CallbackMessageId::UNPREPARE);
99 int32_t ret = DeviceStatusClient::GetInstance().UnprepareCoordination(userData, isCompatible);
100 if (ret != RET_OK) {
101 FI_HILOGE("Unprepare coordination failed");
102 return ret;
103 }
104 return RET_OK;
105 }
106
ActivateCoordination(const std::string & remoteNetworkId,int32_t startDeviceId,FuncCoordinationMessage callback,bool isCompatible)107 int32_t CoordinationManagerImpl::ActivateCoordination(const std::string &remoteNetworkId,
108 int32_t startDeviceId, FuncCoordinationMessage callback, bool isCompatible)
109 {
110 CALL_DEBUG_ENTER;
111 std::lock_guard<std::mutex> guard(mtx_);
112 SetMessageCallback(CallbackMessageId::ACTIVATE, callback);
113 int32_t userData = static_cast<int32_t> (CallbackMessageId::ACTIVATE);
114 int32_t ret = DeviceStatusClient::GetInstance().ActivateCoordination(
115 userData, remoteNetworkId, startDeviceId, isCompatible);
116 if (ret != RET_OK) {
117 FI_HILOGE("Activate coordination failed");
118 return ret;
119 }
120 return RET_OK;
121 }
122
DeactivateCoordination(bool isUnchained,FuncCoordinationMessage callback,bool isCompatible)123 int32_t CoordinationManagerImpl::DeactivateCoordination(bool isUnchained, FuncCoordinationMessage callback,
124 bool isCompatible)
125 {
126 CALL_DEBUG_ENTER;
127 std::lock_guard<std::mutex> guard(mtx_);
128 SetMessageCallback(CallbackMessageId::DEACTIVATE, callback);
129 int32_t userData = static_cast<int32_t> (CallbackMessageId::DEACTIVATE);
130 int32_t ret = DeviceStatusClient::GetInstance().DeactivateCoordination(userData, isUnchained, isCompatible);
131 if (ret != RET_OK) {
132 FI_HILOGE("Deactivate coordination failed");
133 return ret;
134 }
135 return RET_OK;
136 }
137
GetCoordinationState(const std::string & networkId,FuncCoordinationState callback,bool isCompatible)138 int32_t CoordinationManagerImpl::GetCoordinationState(
139 const std::string &networkId, FuncCoordinationState callback, bool isCompatible)
140 {
141 CALL_DEBUG_ENTER;
142 std::lock_guard<std::mutex> guard(mtx_);
143 SetStateCallback(CallbackMessageId::GET_COORDINATION, callback);
144 int32_t userData = static_cast<int32_t> (CallbackMessageId::GET_COORDINATION);
145 int32_t ret = DeviceStatusClient::GetInstance().GetCoordinationState(userData, networkId, isCompatible);
146 if (ret != RET_OK) {
147 FI_HILOGE("Get coordination state failed, ret:%{public}d", ret);
148 return ret;
149 }
150 return RET_OK;
151 }
152
GetCoordinationState(const std::string & udId,bool & state)153 int32_t CoordinationManagerImpl::GetCoordinationState(const std::string &udId, bool &state)
154 {
155 CALL_DEBUG_ENTER;
156 std::lock_guard<std::mutex> guard(mtx_);
157 int32_t ret = DeviceStatusClient::GetInstance().GetCoordinationState(udId, state);
158 if (ret != RET_OK) {
159 FI_HILOGE("Get coordination state failed, ret:%{public}d", ret);
160 return ret;
161 }
162 return RET_OK;
163 }
164
OnDevCoordinationListener(const std::string networkId,CoordinationMessage msg)165 void CoordinationManagerImpl::OnDevCoordinationListener(const std::string networkId, CoordinationMessage msg)
166 {
167 CALL_DEBUG_ENTER;
168 std::lock_guard<std::mutex> guard(mtx_);
169 for (const auto &item : devCoordinationListener_) {
170 item->OnCoordinationMessage(networkId, msg);
171 }
172 }
173
OnCoordinationMessageEvent(int32_t userData,const std::string networkId,CoordinationMessage msg)174 void CoordinationManagerImpl::OnCoordinationMessageEvent(int32_t userData,
175 const std::string networkId, CoordinationMessage msg)
176 {
177 CALL_DEBUG_ENTER;
178 CHK_PID_AND_TID();
179 std::lock_guard<std::mutex> guard(mtx_);
180 if (devCoordinationEvent_.find(userData) == devCoordinationEvent_.end()) {
181 FI_HILOGE("No callback for CallbackMessageId:%{public}d", userData);
182 return;
183 }
184 CoordinationMsg event = devCoordinationEvent_[userData].msg;
185 CHKPV(event);
186 event(networkId, msg);
187 FI_HILOGD("Coordination msg event callback, userData:%{public}d, networkId:%{public}s",
188 userData, GetAnonyString(networkId).c_str());
189 }
190
OnCoordinationStateEvent(int32_t userData,bool state)191 void CoordinationManagerImpl::OnCoordinationStateEvent(int32_t userData, bool state)
192 {
193 CALL_DEBUG_ENTER;
194 CHK_PID_AND_TID();
195 std::lock_guard<std::mutex> guard(mtx_);
196 if (devCoordinationEvent_.find(userData) == devCoordinationEvent_.end()) {
197 FI_HILOGE("No callback for CallbackMessageId:%{public}d", userData);
198 return;
199 }
200 CoordinationState event = devCoordinationEvent_[userData].state;
201 CHKPV(event);
202 event(state);
203 FI_HILOGD("Coordination state event callback, userData:%{public}d", userData);
204 }
205
SetMessageCallback(CallbackMessageId id,FuncCoordinationMessage callback)206 void CoordinationManagerImpl::SetMessageCallback(CallbackMessageId id, FuncCoordinationMessage callback)
207 {
208 CoordinationEvent event;
209 event.msg = callback;
210 devCoordinationEvent_[static_cast<int32_t>(id)] = event;
211 FI_HILOGD("SetMessageCallback for CallbackMessageId:%{public}d", id);
212 }
213
SetStateCallback(CallbackMessageId id,FuncCoordinationState callback)214 void CoordinationManagerImpl::SetStateCallback(CallbackMessageId id, FuncCoordinationState callback)
215 {
216 CoordinationEvent event;
217 event.state = callback;
218 devCoordinationEvent_[static_cast<int32_t>(id)] = event;
219 FI_HILOGD("SetStateCallback for CallbackMessageId:%{public}d", id);
220 }
221
OnCoordinationListener(const StreamClient & client,NetPacket & pkt)222 int32_t CoordinationManagerImpl::OnCoordinationListener(const StreamClient &client, NetPacket &pkt)
223 {
224 CALL_DEBUG_ENTER;
225 int32_t userData = 0;
226 std::string networkId;
227 int32_t nType = 0;
228 pkt >> userData >> networkId >> nType;
229 if (pkt.ChkRWError()) {
230 FI_HILOGE("Packet read type failed");
231 return RET_ERR;
232 }
233 FI_HILOGI("UserData:%{public}d, networkId:%{public}s, nType:%{public}d",
234 userData, GetAnonyString(networkId).c_str(), nType);
235 OnDevCoordinationListener(networkId, CoordinationMessage(nType));
236 return RET_OK;
237 }
238
OnCoordinationMessage(const StreamClient & client,NetPacket & pkt)239 int32_t CoordinationManagerImpl::OnCoordinationMessage(const StreamClient &client, NetPacket &pkt)
240 {
241 CALL_DEBUG_ENTER;
242 int32_t userData = 0;
243 std::string networkId;
244 int32_t nType = 0;
245 pkt >> userData >> networkId >> nType;
246 if (pkt.ChkRWError()) {
247 FI_HILOGE("Packet read coordination msg failed");
248 return RET_ERR;
249 }
250 FI_HILOGI("UserData:%{public}d, networkId:%{public}s, nType:%{public}d",
251 userData, GetAnonyString(networkId).c_str(), nType);
252 OnCoordinationMessageEvent(userData, networkId, CoordinationMessage(nType));
253 return RET_OK;
254 }
255
OnCoordinationState(const StreamClient & client,NetPacket & pkt)256 int32_t CoordinationManagerImpl::OnCoordinationState(const StreamClient &client, NetPacket &pkt)
257 {
258 CALL_DEBUG_ENTER;
259 int32_t userData = 0;
260 bool state = false;
261 pkt >> userData >> state;
262 if (pkt.ChkRWError()) {
263 FI_HILOGE("Packet read coordination msg failed");
264 return RET_ERR;
265 }
266 FI_HILOGI("UserData:%{public}d, state:%{public}s", userData, (state ? "true" : "false"));
267 OnCoordinationStateEvent(userData, state);
268 return RET_OK;
269 }
270
AddHotAreaListener(HotAreaListenerPtr listener)271 int32_t CoordinationManagerImpl::AddHotAreaListener(HotAreaListenerPtr listener)
272 {
273 CALL_DEBUG_ENTER;
274 CHKPR(listener, RET_ERR);
275 std::lock_guard<std::mutex> guard(mtx_);
276 for (const auto &item : devHotAreaListener_) {
277 if (item == listener) {
278 FI_HILOGW("The listener already exists");
279 return RET_ERR;
280 }
281 }
282 if (!isHotAreaListener_) {
283 FI_HILOGI("Start monitoring");
284 int32_t ret = DeviceStatusClient::GetInstance().AddHotAreaListener();
285 if (ret != RET_OK) {
286 FI_HILOGE("Failed to add hot area listener, ret:%{public}d", ret);
287 return ret;
288 }
289 isHotAreaListener_ = true;
290 }
291 devHotAreaListener_.push_back(listener);
292 return RET_OK;
293 }
294
OnDevHotAreaListener(int32_t displayX,int32_t displayY,HotAreaType type,bool isEdge)295 void CoordinationManagerImpl::OnDevHotAreaListener(int32_t displayX,
296 int32_t displayY, HotAreaType type, bool isEdge)
297 {
298 CALL_DEBUG_ENTER;
299 std::lock_guard<std::mutex> guard(mtx_);
300 for (const auto &item : devHotAreaListener_) {
301 item->OnHotAreaMessage(displayX, displayY, type, isEdge);
302 }
303 }
304
OnHotAreaListener(const StreamClient & client,NetPacket & pkt)305 int32_t CoordinationManagerImpl::OnHotAreaListener(const StreamClient &client, NetPacket &pkt)
306 {
307 CALL_DEBUG_ENTER;
308 int32_t positionX = 0;
309 int32_t positionY = 0;
310 int32_t type = 0;
311 bool isEdge = false;
312 pkt >> positionX >> positionY >> type >> isEdge;
313 if (pkt.ChkRWError()) {
314 FI_HILOGE("Packet read type failed");
315 return RET_ERR;
316 }
317 OnDevHotAreaListener(positionX, positionY, HotAreaType(type), isEdge);
318 return RET_OK;
319 }
320
RemoveHotAreaListener(HotAreaListenerPtr listener)321 int32_t CoordinationManagerImpl::RemoveHotAreaListener(HotAreaListenerPtr listener)
322 {
323 CALL_DEBUG_ENTER;
324 std::lock_guard<std::mutex> guard(mtx_);
325 if (listener == nullptr) {
326 devHotAreaListener_.clear();
327 } else {
328 devHotAreaListener_.erase(std::remove_if(devHotAreaListener_.begin(), devHotAreaListener_.end(),
329 [listener] (auto items) {
330 return items == listener;
331 })
332 );
333 }
334
335 if (isHotAreaListener_ && devHotAreaListener_.empty()) {
336 isHotAreaListener_ = false;
337 return DeviceStatusClient::GetInstance().RemoveHotAreaListener();
338 }
339 return RET_OK;
340 }
341
OnConnected()342 void CoordinationManagerImpl::OnConnected()
343 {
344 CALL_INFO_TRACE;
345 CHKPV(prepareCooCallback_);
346 if (PrepareCoordination(prepareCooCallback_, isPrepareCooIsCompatible_) != RET_OK) {
347 FI_HILOGE("PrepareCoordination failed");
348 }
349 }
350
351 } // namespace DeviceStatus
352 } // namespace Msdp
353 } // namespace OHOS