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_sm.h"
17
18 #include <cstdio>
19 #include <unistd.h>
20
21 #include "device_manager.h"
22 #include "display_info.h"
23 #include "display_manager.h"
24 #include "hitrace_meter.h"
25 #include "input_manager.h"
26
27 #include "coordination_device_manager.h"
28 #include "coordination_event_manager.h"
29 #include "coordination_message.h"
30 #include "coordination_softbus_adapter.h"
31 #include "coordination_state_free.h"
32 #include "coordination_state_in.h"
33 #include "coordination_state_out.h"
34 #include "coordination_util.h"
35 #include "device_profile_adapter.h"
36
37 namespace OHOS {
38 namespace Msdp {
39 namespace DeviceStatus {
40 namespace {
41 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "CoordinationSM" };
42 constexpr int32_t INTERVAL_MS { 2000 };
43 constexpr double PERCENT_CONST { 100.0 };
44 constexpr float MOUSE_ABS_LOCATION { 100 };
45 constexpr int32_t MOUSE_ABS_LOCATION_X { 50 };
46 constexpr int32_t MOUSE_ABS_LOCATION_Y { 50 };
47 constexpr int32_t COORDINATION_PRIORITY { 499 };
48 constexpr int32_t MIN_HANDLER_ID { 1 };
49 } // namespace
50
CoordinationSM()51 CoordinationSM::CoordinationSM() {}
~CoordinationSM()52 CoordinationSM::~CoordinationSM()
53 {
54 RemoveMonitor();
55 RemoveInterceptor();
56 }
57
Init()58 void CoordinationSM::Init()
59 {
60 CALL_INFO_TRACE;
61 preparedNetworkId_ = std::make_pair("", "");
62 coordinationStates_.emplace(CoordinationState::STATE_FREE, std::make_shared<CoordinationStateFree>());
63 coordinationStates_.emplace(CoordinationState::STATE_IN, std::make_shared<CoordinationStateIn>());
64 coordinationStates_.emplace(CoordinationState::STATE_OUT, std::make_shared<CoordinationStateOut>());
65 auto *context = COOR_EVENT_MGR->GetIContext();
66 CHKPV(context);
67 context->GetTimerManager().AddTimer(INTERVAL_MS, 1, [this]() {
68 this->InitDeviceManager();
69 COOR_SOFTBUS_ADAPTER->Init();
70 });
71 COOR_DEV_MGR->Init();
72 runner_ = AppExecFwk::EventRunner::Create(true);
73 CHKPL(runner_);
74 eventHandler_ = std::make_shared<CoordinationEventHandler>(runner_);
75 }
OnSoftbusSessionClosed(const std::string & NetworkId)76 void CoordinationSM::OnSoftbusSessionClosed(const std::string &NetworkId)
77 {
78 CALL_INFO_TRACE;
79 CHKPV(eventHandler_);
80 std::string taskName = "process_coordinition_reset";
81 std::function<void()> handleFunc =
82 std::bind(&CoordinationSM::OnReset, this, NetworkId);
83 eventHandler_->ProxyPostTask(handleFunc, taskName, 0);
84 }
85
OnReset(const std::string & NetworkId)86 void CoordinationSM::OnReset(const std::string &NetworkId)
87 {
88 CALL_INFO_TRACE;
89 Reset(NetworkId);
90 }
91
OnSessionLost(SessionPtr session)92 void CoordinationSM::OnSessionLost(SessionPtr session)
93 {
94 CALL_DEBUG_ENTER;
95 CHKPV(session);
96 sptr<CoordinationEventManager::EventInfo> event = new (std::nothrow) CoordinationEventManager::EventInfo();
97 CHKPV(event);
98 event->type = CoordinationEventManager::EventType::LISTENER;
99 event->sess = session;
100 COOR_EVENT_MGR->RemoveCoordinationEvent(event);
101 RemoveMonitor();
102 RemoveInterceptor();
103 if (currentState_ != CoordinationState::STATE_FREE) {
104 DeactivateCoordination(COOR_SM->isUnchained_);
105 }
106 }
107
Reset(const std::string & networkId)108 void CoordinationSM::Reset(const std::string &networkId)
109 {
110 CALL_INFO_TRACE;
111 std::lock_guard<std::mutex> guard(mutex_);
112 bool needReset = true;
113 if (currentState_ == CoordinationState::STATE_OUT) {
114 if (networkId != remoteNetworkId_) {
115 needReset = false;
116 }
117 }
118 if (currentState_ == CoordinationState::STATE_IN) {
119 std::string originNetworkId = COOR_DEV_MGR->GetOriginNetworkId(startDeviceDhid_);
120 if (networkId != originNetworkId) {
121 needReset = false;
122 }
123 }
124 if (needReset) {
125 Reset(true);
126 SetPointerVisible();
127 }
128 }
129
Reset(bool adjustAbsolutionLocation)130 void CoordinationSM::Reset(bool adjustAbsolutionLocation)
131 {
132 CALL_INFO_TRACE;
133 startDeviceDhid_ = "";
134 remoteNetworkId_ = "";
135 currentState_ = CoordinationState::STATE_FREE;
136 if (adjustAbsolutionLocation) {
137 SetAbsolutionLocation(MOUSE_ABS_LOCATION_X, MOUSE_ABS_LOCATION_Y);
138 }
139 isStarting_ = false;
140 isStopping_ = false;
141 RemoveInterceptor();
142 }
143
OnCoordinationChanged(const std::string & networkId,bool isOpen)144 void CoordinationSM::OnCoordinationChanged(const std::string &networkId, bool isOpen)
145 {
146 CALL_DEBUG_ENTER;
147 CoordinationMessage msg = isOpen ? CoordinationMessage::PREPARE : CoordinationMessage::UNPREPARE;
148 auto *context = COOR_EVENT_MGR->GetIContext();
149 CHKPV(context);
150 int32_t ret = context->GetDelegateTasks().PostAsyncTask(
151 std::bind(&CoordinationEventManager::OnCoordinationMessage, COOR_EVENT_MGR, msg, networkId));
152 if (ret != RET_OK) {
153 FI_HILOGE("Posting async task failed");
154 }
155 if (!isOpen) {
156 OnCloseCoordination(networkId, false);
157 }
158 }
159
OnCloseCoordination(const std::string & networkId,bool isLocal)160 void CoordinationSM::OnCloseCoordination(const std::string &networkId, bool isLocal)
161 {
162 CALL_INFO_TRACE;
163 std::lock_guard<std::mutex> guard(mutex_);
164 if (!preparedNetworkId_.first.empty() && !preparedNetworkId_.second.empty()) {
165 if (networkId == preparedNetworkId_.first || networkId == preparedNetworkId_.second) {
166 if (currentState_ != CoordinationState::STATE_FREE) {
167 D_INPUT_ADAPTER->StopRemoteInput(preparedNetworkId_.first, preparedNetworkId_.second,
168 COOR_DEV_MGR->GetCoordinationDhids(startDeviceDhid_), [](bool isSuccess) {
169 FI_HILOGI("Failed to stop remote");
170 });
171 }
172 D_INPUT_ADAPTER->UnPrepareRemoteInput(preparedNetworkId_.first, preparedNetworkId_.second,
173 [](bool isSuccess) {});
174 }
175 }
176 preparedNetworkId_ = std::make_pair("", "");
177 if (currentState_ == CoordinationState::STATE_FREE) {
178 return;
179 }
180 if (isLocal || networkId == remoteNetworkId_) {
181 Reset(true);
182 SetPointerVisible();
183 return;
184 }
185 if (COOR_DEV_MGR->GetOriginNetworkId(startDeviceDhid_) == networkId) {
186 Reset();
187 SetPointerVisible();
188 }
189 }
190
GetCoordinationState(const std::string & deviceId)191 int32_t CoordinationSM::GetCoordinationState(const std::string &deviceId)
192 {
193 CALL_INFO_TRACE;
194 if (deviceId.empty()) {
195 FI_HILOGE("DeviceId is empty");
196 return static_cast<int32_t>(CoordinationMessage::PARAMETER_ERROR);
197 }
198 bool state = DP_ADAPTER->GetCrossingSwitchState(deviceId);
199 COOR_EVENT_MGR->OnGetCrossingSwitchState(state);
200 return RET_OK;
201 }
202
PrepareCoordination()203 void CoordinationSM::PrepareCoordination()
204 {
205 CALL_INFO_TRACE;
206 if (monitorId_ <= 0) {
207 auto monitor = std::make_shared<MonitorConsumer>(
208 std::bind(&CoordinationSM::UpdateLastPointerEventCallback, this, std::placeholders::_1));
209 monitorId_ = MMI::InputManager::GetInstance()->AddMonitor(monitor);
210 if (monitorId_ <= 0) {
211 FI_HILOGE("Failed to add monitor, error code:%{public}d", monitorId_);
212 monitorId_ = -1;
213 return;
214 }
215 }
216 DP_ADAPTER->UpdateCrossingSwitchState(true, onlineDevice_);
217 }
218
UnprepareCoordination()219 void CoordinationSM::UnprepareCoordination()
220 {
221 CALL_INFO_TRACE;
222 DP_ADAPTER->UpdateCrossingSwitchState(false, onlineDevice_);
223 std::string localNetworkId = COORDINATION::GetLocalNetworkId();
224 OnCloseCoordination(localNetworkId, true);
225 RemoveMonitor();
226 }
227
ActivateCoordination(const std::string & remoteNetworkId,int32_t startDeviceId)228 int32_t CoordinationSM::ActivateCoordination(const std::string &remoteNetworkId, int32_t startDeviceId)
229 {
230 CALL_INFO_TRACE;
231 std::lock_guard<std::mutex> guard(mutex_);
232 if (isStarting_) {
233 FI_HILOGE("In transition state, not process");
234 return static_cast<int32_t>(CoordinationMessage::COORDINATION_FAIL);
235 }
236 if (COOR_SOFTBUS_ADAPTER->OpenInputSoftbus(remoteNetworkId) != RET_OK) {
237 FI_HILOGE("Open input softbus fail");
238 return static_cast<int32_t>(CoordinationMessage::COORDINATION_FAIL);
239 }
240 isStarting_ = true;
241 SetSinkNetworkId(remoteNetworkId);
242 auto state = GetCurrentState();
243 CHKPR(state, ERROR_NULL_POINTER);
244 int32_t ret = state->ActivateCoordination(remoteNetworkId, startDeviceId);
245 if (ret != RET_OK) {
246 FI_HILOGE("Start remote input fail");
247 isStarting_ = false;
248 return ret;
249 }
250 UpdateMouseLocation();
251 if (currentState_ == CoordinationState::STATE_FREE) {
252 remoteNetworkId_ = remoteNetworkId;
253 }
254 return ret;
255 }
256
DeactivateCoordination(bool isUnchained)257 int32_t CoordinationSM::DeactivateCoordination(bool isUnchained)
258 {
259 CALL_INFO_TRACE;
260 std::lock_guard<std::mutex> guard(mutex_);
261 if (isStopping_) {
262 FI_HILOGE("In transition state, not process");
263 return RET_ERR;
264 }
265
266 isStopping_ = true;
267 std::string stopNetworkId;
268 if (currentState_ == CoordinationState::STATE_IN) {
269 stopNetworkId = COOR_DEV_MGR->GetOriginNetworkId(startDeviceDhid_);
270 } else if (currentState_ == CoordinationState::STATE_OUT) {
271 stopNetworkId = remoteNetworkId_;
272 } else {
273 stopNetworkId = sinkNetworkId_;
274 }
275 isUnchained_ = isUnchained;
276 FI_HILOGD("isUnchained_:%{public}d, stopNetworkId:%{public}s",
277 isUnchained_, stopNetworkId.substr(0, SUBSTR_NETWORKID_LEN).c_str());
278 auto state = GetCurrentState();
279 CHKPR(state, ERROR_NULL_POINTER);
280 int32_t ret = state->DeactivateCoordination(stopNetworkId, isUnchained, preparedNetworkId_);
281 if (ret != RET_OK) {
282 FI_HILOGE("Stop input device coordination fail");
283 isStopping_ = false;
284 }
285 CHKPR(notifyDragCancelCallback_, ERROR_NULL_POINTER);
286 notifyDragCancelCallback_();
287 return ret;
288 }
289
RegisterNotifyDragCancel(std::function<void (void)> callback)290 void CoordinationSM::RegisterNotifyDragCancel(std::function<void(void)> callback)
291 {
292 CALL_DEBUG_ENTER;
293 CHKPV(callback);
294 notifyDragCancelCallback_ = callback;
295 }
296
StartRemoteCoordination(const std::string & remoteNetworkId,bool buttonIsPressed)297 void CoordinationSM::StartRemoteCoordination(const std::string &remoteNetworkId, bool buttonIsPressed)
298 {
299 CALL_INFO_TRACE;
300 std::lock_guard<std::mutex> guard(mutex_);
301 auto *context = COOR_EVENT_MGR->GetIContext();
302 CHKPV(context);
303 COOR_SM->SetSinkNetworkId(remoteNetworkId);
304 FI_HILOGD("The remoteNetworkId:%{public}s", remoteNetworkId.substr(0, SUBSTR_NETWORKID_LEN).c_str());
305 int32_t ret = context->GetDelegateTasks().PostAsyncTask(std::bind(&CoordinationEventManager::OnCoordinationMessage,
306 COOR_EVENT_MGR, CoordinationMessage::ACTIVATE, remoteNetworkId));
307 if (ret != RET_OK) {
308 FI_HILOGE("Posting async task failed");
309 }
310 isStarting_ = true;
311 if (buttonIsPressed) {
312 MMI::InputManager::GetInstance()->EnableInputDevice(true);
313 StartPointerEventFilter();
314 COOR_SOFTBUS_ADAPTER->NotifyFilterAdded(sinkNetworkId_);
315 }
316 NotifyRemoteNetworkId(remoteNetworkId);
317 }
318
StartPointerEventFilter()319 void CoordinationSM::StartPointerEventFilter()
320 {
321 CALL_INFO_TRACE;
322 int32_t POINTER_DEFAULT_PRIORITY = 220;
323 auto filter = std::make_shared<PointerFilter>();
324 uint32_t touchTags = CapabilityToTags(MMI::INPUT_DEV_CAP_POINTER);
325 FI_HILOGE("Touchtags:%{public}d", static_cast<int32_t>(touchTags));
326 if (filterId_ >= 0) {
327 MMI::InputManager::GetInstance()->RemoveInputEventFilter(filterId_);
328 }
329 filterId_ =
330 MMI::InputManager::GetInstance()->AddInputEventFilter(filter, POINTER_DEFAULT_PRIORITY, touchTags);
331 if (0 > filterId_) {
332 FI_HILOGE("Add Event Filter Failed");
333 }
334 filter->UpdateCurrentFilterId(filterId_);
335 }
336
StartRemoteCoordinationResult(bool isSuccess,const std::string & startDeviceDhid,int32_t xPercent,int32_t yPercent)337 void CoordinationSM::StartRemoteCoordinationResult(bool isSuccess, const std::string &startDeviceDhid, int32_t xPercent,
338 int32_t yPercent)
339 {
340 CALL_INFO_TRACE;
341 std::lock_guard<std::mutex> guard(mutex_);
342 if (!isStarting_) {
343 FI_HILOGI("Not in starting");
344 return;
345 }
346 startDeviceDhid_ = startDeviceDhid;
347 CoordinationMessage msg = isSuccess ? CoordinationMessage::ACTIVATE_SUCCESS : CoordinationMessage::ACTIVATE_FAIL;
348 auto *context = COOR_EVENT_MGR->GetIContext();
349 CHKPV(context);
350 int32_t ret = context->GetDelegateTasks().PostAsyncTask(
351 std::bind(&CoordinationEventManager::OnCoordinationMessage, COOR_EVENT_MGR, msg, ""));
352 if (ret != RET_OK) {
353 FI_HILOGE("Posting async task failed");
354 }
355
356 if (!isSuccess || currentState_ == CoordinationState::STATE_IN) {
357 isStarting_ = false;
358 return;
359 }
360 if (currentState_ == CoordinationState::STATE_FREE) {
361 NotifyMouseLocation(xPercent, yPercent);
362 UpdateState(CoordinationState::STATE_IN);
363 #ifdef OHOS_BUILD_ENABLE_MOTION_DRAG
364 NotifyRemoteNetworkId(COOR_DEV_MGR->GetOriginNetworkId(startDeviceDhid_));
365 StateChangedNotify(CoordinationState::STATE_FREE, CoordinationState::STATE_IN);
366 #else
367 SetAbsolutionLocation(MOUSE_ABS_LOCATION - xPercent, yPercent);
368 MMI::InputManager::GetInstance()->SetPointerVisible(true);
369 #endif // OHOS_BUILD_ENABLE_MOTION_DRAG
370 }
371 if (currentState_ == CoordinationState::STATE_OUT) {
372 NotifyMouseLocation(xPercent, yPercent);
373 UpdateState(CoordinationState::STATE_FREE);
374 #ifdef OHOS_BUILD_ENABLE_MOTION_DRAG
375 NotifyRemoteNetworkId(remoteNetworkId_);
376 StateChangedNotify(CoordinationState::STATE_OUT, CoordinationState::STATE_FREE);
377 #else
378 SetAbsolutionLocation(MOUSE_ABS_LOCATION - xPercent, yPercent);
379 MMI::InputManager::GetInstance()->SetPointerVisible(true);
380 #endif // OHOS_BUILD_ENABLE_MOTION_DRAG
381 }
382 isStarting_ = false;
383 }
384
StopRemoteCoordination(bool isUnchained)385 void CoordinationSM::StopRemoteCoordination(bool isUnchained)
386 {
387 CALL_INFO_TRACE;
388 std::lock_guard<std::mutex> guard(mutex_);
389 isStopping_ = true;
390 isUnchained_ = isUnchained;
391 }
392
StopRemoteCoordinationResult(bool isSuccess)393 void CoordinationSM::StopRemoteCoordinationResult(bool isSuccess)
394 {
395 CALL_INFO_TRACE;
396 std::lock_guard<std::mutex> guard(mutex_);
397 if (!isStopping_) {
398 FI_HILOGI("Not in stopping");
399 return;
400 }
401 if (isSuccess) {
402 Reset(true);
403 SetPointerVisible();
404 }
405 if (!preparedNetworkId_.first.empty() && !preparedNetworkId_.second.empty() && isUnchained_) {
406 FI_HILOGI("The sink preparedNetworkId isn't empty, first:%{public}s, second:%{public}s",
407 preparedNetworkId_.first.c_str(), preparedNetworkId_.second.c_str());
408 bool ret = UnchainCoordination(preparedNetworkId_.first, preparedNetworkId_.second);
409 if (ret) {
410 COOR_SM->NotifyChainRemoved();
411 std::string localNetworkId = COORDINATION::GetLocalNetworkId();
412 FI_HILOGD("localNetworkId:%{public}s", localNetworkId.substr(0, SUBSTR_NETWORKID_LEN).c_str());
413 COOR_SOFTBUS_ADAPTER->NotifyUnchainedResult(localNetworkId, sinkNetworkId_, ret);
414 } else {
415 FI_HILOGE("Failed to unchain coordination");
416 }
417 isUnchained_ = false;
418 }
419 isStopping_ = false;
420 }
421
StartCoordinationOtherResult(const std::string & remoteNetworkId)422 void CoordinationSM::StartCoordinationOtherResult(const std::string &remoteNetworkId)
423 {
424 CALL_INFO_TRACE;
425 std::lock_guard<std::mutex> guard(mutex_);
426 remoteNetworkId_ = remoteNetworkId;
427 }
428
OnStartFinish(bool isSuccess,const std::string & remoteNetworkId,int32_t startDeviceId)429 void CoordinationSM::OnStartFinish(bool isSuccess, const std::string &remoteNetworkId, int32_t startDeviceId)
430 {
431 CALL_INFO_TRACE;
432 std::lock_guard<std::mutex> guard(mutex_);
433 if (!isStarting_) {
434 FI_HILOGE("Not in starting");
435 return;
436 }
437
438 if (!isSuccess) {
439 FI_HILOGE("Start distributed fail, startDevice:%{public}d", startDeviceId);
440 NotifyRemoteStartFail(remoteNetworkId);
441 } else {
442 startDeviceDhid_ = COOR_DEV_MGR->GetDhid(startDeviceId);
443 if (currentState_ == CoordinationState::STATE_FREE) {
444 #ifdef OHOS_BUILD_ENABLE_MOTION_DRAG
445 NotifyRemoteNetworkId(remoteNetworkId);
446 NotifyMouseLocation(mouseLocation_.first, mouseLocation_.second);
447 StateChangedNotify(CoordinationState::STATE_FREE, CoordinationState::STATE_OUT);
448 #endif // OHOS_BUILD_ENABLE_MOTION_DRAG
449 } else if (currentState_ == CoordinationState::STATE_IN) {
450 std::string originNetworkId = COOR_DEV_MGR->GetOriginNetworkId(startDeviceId);
451 if (!originNetworkId.empty() && remoteNetworkId != originNetworkId) {
452 COOR_SOFTBUS_ADAPTER->StartCoordinationOtherResult(originNetworkId, remoteNetworkId);
453 }
454 #ifdef OHOS_BUILD_ENABLE_MOTION_DRAG
455 NotifyRemoteNetworkId(originNetworkId);
456 NotifyMouseLocation(mouseLocation_.first, mouseLocation_.second);
457 StateChangedNotify(CoordinationState::STATE_IN, CoordinationState::STATE_FREE);
458 #endif // OHOS_BUILD_ENABLE_MOTION_DRAG
459 SetPointerVisible();
460 }
461 NotifyRemoteStartSuccess(remoteNetworkId, startDeviceDhid_);
462 if (currentState_ == CoordinationState::STATE_FREE) {
463 UpdateState(CoordinationState::STATE_OUT);
464 } else if (currentState_ == CoordinationState::STATE_IN) {
465 UpdateState(CoordinationState::STATE_FREE);
466 } else {
467 FI_HILOGI("Current state is out");
468 }
469 }
470 isStarting_ = false;
471 }
472
OnStopFinish(bool isSuccess,const std::string & remoteNetworkId)473 void CoordinationSM::OnStopFinish(bool isSuccess, const std::string &remoteNetworkId)
474 {
475 CALL_INFO_TRACE;
476 std::lock_guard<std::mutex> guard(mutex_);
477 if (!isStopping_) {
478 FI_HILOGE("Not in stopping");
479 return;
480 }
481 NotifyRemoteStopFinish(isSuccess, remoteNetworkId);
482 if (isSuccess) {
483 if (COOR_DEV_MGR->HasLocalPointerDevice()) {
484 MMI::InputManager::GetInstance()->SetPointerVisible(true);
485 SetAbsolutionLocation(MOUSE_ABS_LOCATION_X, MOUSE_ABS_LOCATION_Y);
486 }
487 if (currentState_ == CoordinationState::STATE_IN || currentState_ == CoordinationState::STATE_OUT) {
488 UpdateState(CoordinationState::STATE_FREE);
489 #ifdef OHOS_BUILD_ENABLE_MOTION_DRAG
490 NotifyRemoteNetworkId(remoteNetworkId);
491 StateChangedNotify(currentState_, CoordinationState::STATE_FREE);
492 #endif // OHOS_BUILD_ENABLE_MOTION_DRAG
493 } else {
494 FI_HILOGI("Current state is free");
495 }
496 }
497 if (!preparedNetworkId_.first.empty() && !preparedNetworkId_.second.empty() && isUnchained_) {
498 FI_HILOGI("The local preparedNetworkId isn't empty, first:%{public}s, second:%{public}s",
499 preparedNetworkId_.first.c_str(), preparedNetworkId_.second.c_str());
500 bool ret = UnchainCoordination(preparedNetworkId_.first, preparedNetworkId_.second);
501 if (ret) {
502 COOR_SM->NotifyChainRemoved();
503 std::string localNetworkId = COORDINATION::GetLocalNetworkId();
504 FI_HILOGD("localNetworkId:%{public}s", localNetworkId.substr(0, SUBSTR_NETWORKID_LEN).c_str());
505 COOR_SOFTBUS_ADAPTER->NotifyUnchainedResult(localNetworkId, remoteNetworkId, ret);
506 } else {
507 FI_HILOGE("Failed to unchain coordination");
508 }
509 }
510 if (!isUnchained_) {
511 COOR_SOFTBUS_ADAPTER->CloseInputSoftbus(remoteNetworkId);
512 }
513 COOR_SM->SetPointerVisible();
514 isUnchained_ = false;
515 isStopping_ = false;
516 }
517
NotifyRemoteStartFail(const std::string & remoteNetworkId)518 void CoordinationSM::NotifyRemoteStartFail(const std::string &remoteNetworkId)
519 {
520 CALL_DEBUG_ENTER;
521 COOR_SOFTBUS_ADAPTER->StartRemoteCoordinationResult(remoteNetworkId, false, "", 0, 0);
522 COOR_EVENT_MGR->OnStart(CoordinationMessage::ACTIVATE_FAIL);
523 }
524
NotifyRemoteStartSuccess(const std::string & remoteNetworkId,const std::string & startDeviceDhid)525 void CoordinationSM::NotifyRemoteStartSuccess(const std::string &remoteNetworkId, const std::string &startDeviceDhid)
526 {
527 CALL_DEBUG_ENTER;
528 COOR_SOFTBUS_ADAPTER->StartRemoteCoordinationResult(remoteNetworkId, true, startDeviceDhid, mouseLocation_.first,
529 mouseLocation_.second);
530 COOR_EVENT_MGR->OnStart(CoordinationMessage::ACTIVATE_SUCCESS);
531 }
532
NotifyRemoteStopFinish(bool isSuccess,const std::string & remoteNetworkId)533 void CoordinationSM::NotifyRemoteStopFinish(bool isSuccess, const std::string &remoteNetworkId)
534 {
535 CALL_DEBUG_ENTER;
536 COOR_SOFTBUS_ADAPTER->StopRemoteCoordinationResult(remoteNetworkId, isSuccess);
537 if (!isSuccess) {
538 COOR_EVENT_MGR->OnStop(CoordinationMessage::COORDINATION_FAIL);
539 } else {
540 COOR_EVENT_MGR->OnStop(CoordinationMessage::DEACTIVATE_SUCCESS);
541 }
542 }
543
UpdateMouseLocation()544 bool CoordinationSM::UpdateMouseLocation()
545 {
546 CALL_DEBUG_ENTER;
547 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
548 CHKPF(display);
549 int32_t width = display->GetWidth();
550 int32_t height = display->GetHeight();
551 if (width == 0 || height == 0) {
552 FI_HILOGE("display width or height is 0");
553 return false;
554 }
555 int32_t xPercent = displayX_ * MOUSE_ABS_LOCATION / width;
556 int32_t yPercent = displayY_ * MOUSE_ABS_LOCATION / height;
557 FI_HILOGI("displayWidth:%{public}d, displayHeight:%{public}d, "
558 "physicalX:%{public}d, physicalY:%{public}d,",
559 width, height, displayX_, displayY_);
560 mouseLocation_ = std::make_pair(xPercent, yPercent);
561 return true;
562 }
563
UnchainCoordination(const std::string & localNetworkId,const std::string & remoteNetworkId)564 bool CoordinationSM::UnchainCoordination(const std::string &localNetworkId, const std::string &remoteNetworkId)
565 {
566 CALL_DEBUG_ENTER;
567 int32_t ret = D_INPUT_ADAPTER->UnPrepareRemoteInput(localNetworkId, remoteNetworkId, [](bool isSuccess) {});
568 if (ret != RET_OK) {
569 FI_HILOGE("Failed to call distributed UnprepareRemoteInput");
570 return false;
571 }
572 preparedNetworkId_ = std::make_pair("", "");
573 return true;
574 }
575
UpdateState(CoordinationState state)576 void CoordinationSM::UpdateState(CoordinationState state)
577 {
578 FI_HILOGI("state:%{public}d", state);
579 currentState_ = state;
580 switch (state) {
581 case CoordinationState::STATE_FREE: {
582 Reset();
583 MMI::InputManager::GetInstance()->EnableInputDevice(false);
584 break;
585 }
586 case CoordinationState::STATE_IN: {
587 MMI::InputManager::GetInstance()->SetPointerVisible(false);
588 auto interceptor = std::make_shared<InterceptorConsumer>();
589 MMI::InputManager::GetInstance()->EnableInputDevice(true);
590 auto state = GetCurrentState();
591 CHKPV(state);
592 state->SetStartDeviceDhid(startDeviceDhid_);
593 interceptorId_ = MMI::InputManager::GetInstance()->AddInterceptor(interceptor, COORDINATION_PRIORITY,
594 CapabilityToTags(MMI::INPUT_DEV_CAP_KEYBOARD));
595 if (interceptorId_ <= 0) {
596 FI_HILOGE("Failed to add interceptor, Error code:%{public}d", interceptorId_);
597 DeactivateCoordination(isUnchained_);
598 return;
599 }
600 COOR_SOFTBUS_ADAPTER->ConfigTcpAlive();
601 break;
602 }
603 case CoordinationState::STATE_OUT: {
604 MMI::InputManager::GetInstance()->SetPointerVisible(false);
605 auto interceptor = std::make_shared<InterceptorConsumer>();
606 interceptorId_ = MMI::InputManager::GetInstance()->AddInterceptor(interceptor, COORDINATION_PRIORITY,
607 CapabilityToTags(MMI::INPUT_DEV_CAP_KEYBOARD) | CapabilityToTags(MMI::INPUT_DEV_CAP_POINTER));
608 auto state = GetCurrentState();
609 CHKPV(state);
610 state->SetStartDeviceDhid(startDeviceDhid_);
611 if (interceptorId_ <= 0) {
612 FI_HILOGE("Failed to add interceptor, Error code:%{public}d", interceptorId_);
613 DeactivateCoordination(isUnchained_);
614 return;
615 }
616 COOR_SOFTBUS_ADAPTER->ConfigTcpAlive();
617 break;
618 }
619 default:
620 break;
621 }
622 }
623
GetCurrentCoordinationState() const624 CoordinationState CoordinationSM::GetCurrentCoordinationState() const
625 {
626 CALL_DEBUG_ENTER;
627 std::lock_guard<std::mutex> guard(mutex_);
628 return currentState_;
629 }
630
UpdatePreparedDevices(const std::string & remoteNetworkId,const std::string & originNetworkId)631 void CoordinationSM::UpdatePreparedDevices(const std::string &remoteNetworkId, const std::string &originNetworkId)
632 {
633 CALL_DEBUG_ENTER;
634 std::lock_guard<std::mutex> guard(mutex_);
635 preparedNetworkId_ = std::make_pair(remoteNetworkId, originNetworkId);
636 }
637
GetPreparedDevices() const638 std::pair<std::string, std::string> CoordinationSM::GetPreparedDevices() const
639 {
640 CALL_DEBUG_ENTER;
641 std::lock_guard<std::mutex> guard(mutex_);
642 return preparedNetworkId_;
643 }
644
IsStarting() const645 bool CoordinationSM::IsStarting() const
646 {
647 std::lock_guard<std::mutex> guard(mutex_);
648 return isStarting_;
649 }
650
IsStopping() const651 bool CoordinationSM::IsStopping() const
652 {
653 std::lock_guard<std::mutex> guard(mutex_);
654 return isStopping_;
655 }
656
OnKeyboardOnline(const std::string & dhid)657 void CoordinationSM::OnKeyboardOnline(const std::string &dhid)
658 {
659 CALL_INFO_TRACE;
660 std::lock_guard<std::mutex> guard(mutex_);
661 auto state = GetCurrentState();
662 CHKPV(state);
663 state->OnKeyboardOnline(dhid, preparedNetworkId_);
664 }
665
OnPointerOffline(const std::string & dhid,const std::vector<std::string> & keyboards)666 void CoordinationSM::OnPointerOffline(const std::string &dhid, const std::vector<std::string> &keyboards)
667 {
668 CALL_INFO_TRACE;
669 std::lock_guard<std::mutex> guard(mutex_);
670 if (currentState_ == CoordinationState::STATE_FREE) {
671 FI_HILOGI("Current state: free");
672 return;
673 }
674 if ((currentState_ == CoordinationState::STATE_IN) && (startDeviceDhid_ == dhid)) {
675 Reset(true);
676 SetPointerVisible();
677 return;
678 }
679 if ((currentState_ == CoordinationState::STATE_OUT) && (startDeviceDhid_ == dhid)) {
680 std::string remoteNetworkId = remoteNetworkId_;
681 if (remoteNetworkId.empty()) {
682 remoteNetworkId = preparedNetworkId_.first;
683 }
684 std::string localNetworkId = COORDINATION::GetLocalNetworkId();
685 D_INPUT_ADAPTER->StopRemoteInput(remoteNetworkId, localNetworkId, keyboards,
686 [this, remoteNetworkId](bool isSuccess) {});
687 Reset(true);
688 SetPointerVisible();
689 }
690 }
691
OnKeyboardOffline(const std::string & dhid)692 void CoordinationSM::OnKeyboardOffline(const std::string &dhid)
693 {
694 CALL_INFO_TRACE;
695 if (currentState_ == CoordinationState::STATE_OUT) {
696 std::string remoteNetworkId = remoteNetworkId_;
697 if (remoteNetworkId.empty()) {
698 remoteNetworkId = preparedNetworkId_.first;
699 }
700 std::string localNetworkId = COORDINATION::GetLocalNetworkId();
701 std::vector<std::string> inputDeviceDhids;
702 inputDeviceDhids.push_back(dhid);
703 D_INPUT_ADAPTER->StopRemoteInput(remoteNetworkId, localNetworkId, inputDeviceDhids,
704 [this, remoteNetworkId](bool isSuccess) {});
705 }
706 }
707
InitDeviceManager()708 bool CoordinationSM::InitDeviceManager()
709 {
710 CALL_DEBUG_ENTER;
711 initCallback_ = std::make_shared<DeviceInitCallBack>();
712 int32_t ret = DIS_HARDWARE.InitDeviceManager(FI_PKG_NAME, initCallback_);
713 if (ret != 0) {
714 FI_HILOGE("Init device manager failed, ret:%{public}d", ret);
715 return false;
716 }
717 stateCallback_ = std::make_shared<DmDeviceStateCallback>();
718 ret = DIS_HARDWARE.RegisterDevStateCallback(FI_PKG_NAME, "", stateCallback_);
719 if (ret != 0) {
720 FI_HILOGE("Register devStateCallback failed, ret:%{public}d", ret);
721 return false;
722 }
723 return true;
724 }
725
OnDeviceOnline(const std::string & networkId)726 void CoordinationSM::OnDeviceOnline(const std::string &networkId)
727 {
728 CALL_INFO_TRACE;
729 std::lock_guard<std::mutex> guard(mutex_);
730 onlineDevice_.push_back(networkId);
731 DP_ADAPTER->RegisterCrossingStateListener(networkId,
732 std::bind(&CoordinationSM::OnCoordinationChanged, COOR_SM, std::placeholders::_1, std::placeholders::_2));
733 COOR_SOFTBUS_ADAPTER->Init();
734 }
735
OnDeviceOffline(const std::string & networkId)736 void CoordinationSM::OnDeviceOffline(const std::string &networkId)
737 {
738 CALL_INFO_TRACE;
739 DP_ADAPTER->UnregisterCrossingStateListener(networkId);
740 Reset(networkId);
741 preparedNetworkId_ = std::make_pair("", "");
742 std::lock_guard<std::mutex> guard(mutex_);
743 if (!onlineDevice_.empty()) {
744 auto it = std::find(onlineDevice_.begin(), onlineDevice_.end(), networkId);
745 if (it != onlineDevice_.end()) {
746 onlineDevice_.erase(it);
747 }
748 }
749 if (currentState_ == CoordinationState::STATE_IN && sinkNetworkId_ == networkId) {
750 COOR_EVENT_MGR->OnCoordinationMessage(CoordinationMessage::SESSION_CLOSED);
751 }
752 if (currentState_ == CoordinationState::STATE_OUT && remoteNetworkId_ == networkId) {
753 COOR_EVENT_MGR->OnCoordinationMessage(CoordinationMessage::SESSION_CLOSED);
754 }
755 }
756
GetDeviceCoordinationState(CoordinationState value) const757 std::string CoordinationSM::GetDeviceCoordinationState(CoordinationState value) const
758 {
759 std::string state;
760 switch (value) {
761 case CoordinationState::STATE_FREE: {
762 state = "free";
763 break;
764 }
765 case CoordinationState::STATE_IN: {
766 state = "in";
767 break;
768 }
769 case CoordinationState::STATE_OUT: {
770 state = "out";
771 break;
772 }
773 default: {
774 state = "unknown";
775 FI_HILOGW("Coordination status unknown");
776 break;
777 }
778 }
779 return state;
780 }
781
Dump(int32_t fd)782 void CoordinationSM::Dump(int32_t fd)
783 {
784 CALL_DEBUG_ENTER;
785 std::lock_guard<std::mutex> guard(mutex_);
786 dprintf(fd, "Coordination information:\n");
787 dprintf(fd,
788 "coordinationState:%s | startDeviceDhid:%s | remoteNetworkId:%s | isStarting:%s | isStopping:%s\n"
789 "physicalX:%d | physicalY:%d | displayX:%d | displayY:%d | interceptorId:%d | monitorId:%d | filterId:%d\n",
790 GetDeviceCoordinationState(currentState_).c_str(), startDeviceDhid_.c_str(),
791 remoteNetworkId_.substr(0, SUBSTR_NETWORKID_LEN).c_str(), isStarting_ ? "true" : "false", isStopping_ ? "true" : "false",
792 mouseLocation_.first, mouseLocation_.second, displayX_, displayY_, interceptorId_, monitorId_, filterId_);
793 if (onlineDevice_.empty()) {
794 dprintf(fd, "onlineDevice:%s\n", "None");
795 return;
796 }
797 for (const auto &item : onlineDevice_) {
798 dprintf(fd, "onlineDevice:%s\n", item.c_str());
799 }
800 }
801
UpdateLastPointerEventCallback(std::shared_ptr<MMI::PointerEvent> pointerEvent)802 void CoordinationSM::UpdateLastPointerEventCallback(std::shared_ptr<MMI::PointerEvent> pointerEvent)
803 {
804 lastPointerEvent_ = pointerEvent;
805 }
806
GetLastPointerEvent() const807 std::shared_ptr<MMI::PointerEvent> CoordinationSM::GetLastPointerEvent() const
808 {
809 return lastPointerEvent_;
810 }
811
RemoveMonitor()812 void CoordinationSM::RemoveMonitor()
813 {
814 if ((monitorId_ >= MIN_HANDLER_ID) && (monitorId_ < std::numeric_limits<int32_t>::max())) {
815 MMI::InputManager::GetInstance()->RemoveMonitor(monitorId_);
816 monitorId_ = -1;
817 }
818 }
819
RemoveInterceptor()820 void CoordinationSM::RemoveInterceptor()
821 {
822 if ((interceptorId_ >= MIN_HANDLER_ID) && (interceptorId_ < std::numeric_limits<int32_t>::max())) {
823 MMI::InputManager::GetInstance()->RemoveInterceptor(interceptorId_);
824 interceptorId_ = -1;
825 }
826 }
827
IsNeedFilterOut(const std::string & deviceId,const std::shared_ptr<MMI::KeyEvent> keyEvent)828 bool CoordinationSM::IsNeedFilterOut(const std::string &deviceId, const std::shared_ptr<MMI::KeyEvent> keyEvent)
829 {
830 CALL_DEBUG_ENTER;
831 std::vector<OHOS::MMI::KeyEvent::KeyItem> KeyItems = keyEvent->GetKeyItems();
832 std::vector<int32_t> KeyItemsForDInput;
833 KeyItemsForDInput.reserve(KeyItems.size());
834 for (const auto &item : KeyItems) {
835 KeyItemsForDInput.push_back(item.GetKeyCode());
836 }
837 DistributedHardware::DistributedInput::BusinessEvent businessEvent;
838 businessEvent.keyCode = keyEvent->GetKeyCode();
839 businessEvent.keyAction = keyEvent->GetKeyAction();
840 businessEvent.pressedKeys = KeyItemsForDInput;
841 FI_HILOGI("businessEvent.keyCode:%{public}d, keyAction:%{public}d",
842 businessEvent.keyCode, businessEvent.keyAction);
843 for (const auto &item : businessEvent.pressedKeys) {
844 FI_HILOGI("pressedKeys:%{public}d", item);
845 }
846 return D_INPUT_ADAPTER->IsNeedFilterOut(deviceId, businessEvent);
847 }
848
OnRemoteDied()849 void CoordinationSM::DeviceInitCallBack::OnRemoteDied()
850 {
851 CALL_INFO_TRACE;
852 }
853
OnDeviceOnline(const DistributedHardware::DmDeviceInfo & deviceInfo)854 void CoordinationSM::DmDeviceStateCallback::OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo)
855 {
856 CALL_DEBUG_ENTER;
857 COOR_SM->OnDeviceOnline(deviceInfo.networkId);
858 }
859
OnDeviceOffline(const DistributedHardware::DmDeviceInfo & deviceInfo)860 void CoordinationSM::DmDeviceStateCallback::OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo)
861 {
862 CALL_INFO_TRACE;
863 COOR_SM->OnDeviceOffline(deviceInfo.networkId);
864 }
865
OnDeviceChanged(const DistributedHardware::DmDeviceInfo & deviceInfo)866 void CoordinationSM::DmDeviceStateCallback::OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo)
867 {
868 CALL_INFO_TRACE;
869 }
870
OnDeviceReady(const DistributedHardware::DmDeviceInfo & deviceInfo)871 void CoordinationSM::DmDeviceStateCallback::OnDeviceReady(const DistributedHardware::DmDeviceInfo &deviceInfo)
872 {
873 CALL_INFO_TRACE;
874 }
875
SetAbsolutionLocation(double xPercent,double yPercent)876 void CoordinationSM::SetAbsolutionLocation(double xPercent, double yPercent)
877 {
878 CALL_INFO_TRACE;
879 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
880 CHKPV(display);
881 int32_t width = display->GetWidth();
882 int32_t height = display->GetHeight();
883 int32_t physicalX = static_cast<int32_t>(width * xPercent / PERCENT_CONST);
884 int32_t physicalY = static_cast<int32_t>(height * yPercent / PERCENT_CONST);
885 FI_HILOGD("width:%{public}d, height:%{public}d, physicalX:%{public}d, physicalY:%{public}d", width, height,
886 physicalX, physicalY);
887 MMI::InputManager::GetInstance()->SetPointerLocation(physicalX, physicalY);
888 }
889
890
OnInterceptorInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)891 void CoordinationSM::OnInterceptorInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
892 {
893 CHKPV(eventHandler_);
894 CHKPV(keyEvent);
895 std::string taskName = "process_interceptor_keyevent";
896 std::function<void()> handleFunc =
897 std::bind(&CoordinationSM::OnPostInterceptorKeyEvent, this, keyEvent);
898 eventHandler_->ProxyPostTask(handleFunc, taskName, 0);
899 }
900
OnInterceptorInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)901 void CoordinationSM::OnInterceptorInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
902 {
903 CHKPV(eventHandler_);
904 CHKPV(pointerEvent);
905 std::string taskName = "process_interceptor_pointerevent";
906 std::function<void()> handleFunc =
907 std::bind(&CoordinationSM::OnPostInterceptorPointerEvent, this, pointerEvent);
908 eventHandler_->ProxyPostTask(handleFunc, taskName, 0);
909 }
910
OnMonitorInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)911 void CoordinationSM::OnMonitorInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
912 {
913 CHKPV(eventHandler_);
914 CHKPV(pointerEvent);
915 std::string taskName = "process_monitor_pointerevent";
916 std::function<void()> handleFunc =
917 std::bind(&CoordinationSM::OnPostMonitorInputEvent, this, pointerEvent);
918 eventHandler_->ProxyPostTask(handleFunc, taskName, 0);
919 }
920
OnPostInterceptorKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)921 void CoordinationSM::OnPostInterceptorKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
922 {
923 CALL_DEBUG_ENTER;
924 CHKPV(keyEvent);
925 int32_t keyCode = keyEvent->GetKeyCode();
926 CoordinationState state = GetCurrentCoordinationState();
927 int32_t deviceId = keyEvent->GetDeviceId();
928 if (keyCode == MMI::KeyEvent::KEYCODE_BACK || keyCode == MMI::KeyEvent::KEYCODE_VOLUME_UP ||
929 keyCode == MMI::KeyEvent::KEYCODE_VOLUME_DOWN || keyCode == MMI::KeyEvent::KEYCODE_POWER) {
930 if ((state == CoordinationState::STATE_OUT) || (!COOR_DEV_MGR->IsRemote(deviceId))) {
931 keyEvent->AddFlag(MMI::AxisEvent::EVENT_FLAG_NO_INTERCEPT);
932 MMI::InputManager::GetInstance()->SimulateInputEvent(keyEvent);
933 }
934 return;
935 }
936 if (state == CoordinationState::STATE_IN) {
937 if (COOR_DEV_MGR->IsRemote(deviceId)) {
938 auto networkId = COOR_DEV_MGR->GetOriginNetworkId(deviceId);
939 if (!IsNeedFilterOut(networkId, keyEvent)) {
940 keyEvent->AddFlag(MMI::AxisEvent::EVENT_FLAG_NO_INTERCEPT);
941 MMI::InputManager::GetInstance()->SimulateInputEvent(keyEvent);
942 }
943 } else {
944 keyEvent->AddFlag(MMI::AxisEvent::EVENT_FLAG_NO_INTERCEPT);
945 MMI::InputManager::GetInstance()->SimulateInputEvent(keyEvent);
946 }
947 } else if (state == CoordinationState::STATE_OUT) {
948 std::string networkId = COORDINATION::GetLocalNetworkId();
949 if (IsNeedFilterOut(networkId, keyEvent)) {
950 keyEvent->AddFlag(MMI::AxisEvent::EVENT_FLAG_NO_INTERCEPT);
951 MMI::InputManager::GetInstance()->SimulateInputEvent(keyEvent);
952 }
953 }
954 }
955
OnPostInterceptorPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)956 void CoordinationSM::OnPostInterceptorPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
957 {
958 CALL_DEBUG_ENTER;
959 CHKPV(pointerEvent);
960 if (pointerEvent->GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
961 FI_HILOGD("Not mouse event, skip");
962 return;
963 }
964 CoordinationState state = GetCurrentCoordinationState();
965 if (state == CoordinationState::STATE_OUT) {
966 int32_t deviceId = pointerEvent->GetDeviceId();
967 std::string dhid = COOR_DEV_MGR->GetDhid(deviceId);
968 if (startDeviceDhid_ != dhid) {
969 FI_HILOGI("Move other mouse, stop input device coordination");
970 DeactivateCoordination(isUnchained_);
971 }
972 }
973 }
974
OnPostMonitorInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)975 void CoordinationSM::OnPostMonitorInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
976 {
977 CALL_DEBUG_ENTER;
978 CHKPV(pointerEvent);
979 MMI::PointerEvent::PointerItem pointerItem;
980 pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem);
981 displayX_ = pointerItem.GetDisplayX();
982 displayY_ = pointerItem.GetDisplayY();
983 CoordinationState state = GetCurrentCoordinationState();
984 if (state == CoordinationState::STATE_IN) {
985 int32_t deviceId = pointerEvent->GetDeviceId();
986 if (!COOR_DEV_MGR->IsRemote(deviceId)) {
987 DeactivateCoordination(isUnchained_);
988 }
989 }
990 }
991
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const992 void CoordinationSM::InterceptorConsumer::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
993 {
994 COOR_SM->OnInterceptorInputEvent(keyEvent);
995 }
996
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const997 void CoordinationSM::InterceptorConsumer::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
998 {
999 COOR_SM->OnInterceptorInputEvent(pointerEvent);
1000 }
1001
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const1002 void CoordinationSM::InterceptorConsumer::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const {}
1003
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const1004 void CoordinationSM::MonitorConsumer::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const {}
1005
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const1006 void CoordinationSM::MonitorConsumer::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
1007 {
1008 CHKPV(pointerEvent);
1009 if (pointerEvent->GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
1010 FI_HILOGD("Not mouse event, skip");
1011 return;
1012 }
1013 if (callback_) {
1014 callback_(pointerEvent);
1015 }
1016 COOR_SM->OnMonitorInputEvent(pointerEvent);
1017 }
1018
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const1019 void CoordinationSM::MonitorConsumer::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const {}
1020
RegisterStateChange(CooStateChangeType type,std::function<void (CoordinationState,CoordinationState)> callback)1021 void CoordinationSM::RegisterStateChange(CooStateChangeType type,
1022 std::function<void(CoordinationState, CoordinationState)> callback)
1023 {
1024 CALL_DEBUG_ENTER;
1025 CHKPV(callback);
1026 stateChangedCallbacks_[type] = callback;
1027 }
1028
RegisterRemoteNetworkId(std::function<void (std::string)> callback)1029 void CoordinationSM::RegisterRemoteNetworkId(std::function<void(std::string)> callback)
1030 {
1031 CALL_DEBUG_ENTER;
1032 CHKPV(callback);
1033 remoteNetworkIdCallback_ = callback;
1034 }
1035
RegisterMouseLocation(std::function<void (int32_t,int32_t)> callback)1036 void CoordinationSM::RegisterMouseLocation(std::function<void(int32_t, int32_t)> callback)
1037 {
1038 CALL_DEBUG_ENTER;
1039 CHKPV(callback);
1040 mouseLocationCallback_ = callback;
1041 }
1042
StateChangedNotify(CoordinationState oldState,CoordinationState newState)1043 void CoordinationSM::StateChangedNotify(CoordinationState oldState, CoordinationState newState)
1044 {
1045 CALL_DEBUG_ENTER;
1046 if (oldState == CoordinationState::STATE_FREE && newState == CoordinationState::STATE_IN) {
1047 ChangeNotify(CooStateChangeType::STATE_FREE_TO_IN, oldState, newState);
1048 return;
1049 }
1050 if (oldState == CoordinationState::STATE_FREE && newState == CoordinationState::STATE_OUT) {
1051 ChangeNotify(CooStateChangeType::STATE_FREE_TO_OUT, oldState, newState);
1052 return;
1053 }
1054 if (oldState == CoordinationState::STATE_IN && newState == CoordinationState::STATE_FREE) {
1055 ChangeNotify(CooStateChangeType::STATE_IN_TO_FREE, oldState, newState);
1056 return;
1057 }
1058 if (oldState == CoordinationState::STATE_OUT && newState == CoordinationState::STATE_FREE) {
1059 ChangeNotify(CooStateChangeType::STATE_OUT_TO_FREE, oldState, newState);
1060 }
1061 }
1062
ChangeNotify(CooStateChangeType type,CoordinationState oldState,CoordinationState newState)1063 void CoordinationSM::ChangeNotify(CooStateChangeType type, CoordinationState oldState, CoordinationState newState)
1064 {
1065 auto item = stateChangedCallbacks_[type];
1066 if (item != nullptr) {
1067 item(oldState, newState);
1068 }
1069 }
1070
NotifyRemoteNetworkId(const std::string & remoteNetworkId)1071 void CoordinationSM::NotifyRemoteNetworkId(const std::string &remoteNetworkId)
1072 {
1073 if (remoteNetworkIdCallback_ != nullptr) {
1074 remoteNetworkIdCallback_(remoteNetworkId);
1075 }
1076 }
1077
NotifyMouseLocation(int32_t x,int32_t y)1078 void CoordinationSM::NotifyMouseLocation(int32_t x, int32_t y)
1079 {
1080 if (mouseLocationCallback_ != nullptr) {
1081 mouseLocationCallback_(x, y);
1082 }
1083 }
1084
SetUnchainStatus(bool isUnchained)1085 void CoordinationSM::SetUnchainStatus(bool isUnchained)
1086 {
1087 CALL_DEBUG_ENTER;
1088 isUnchained_ = isUnchained;
1089 }
1090
NotifyChainRemoved()1091 void CoordinationSM::NotifyChainRemoved()
1092 {
1093 CALL_DEBUG_ENTER;
1094 CoordinationMessage msg = CoordinationMessage::SESSION_CLOSED;
1095 auto *context = COOR_EVENT_MGR->GetIContext();
1096 CHKPV(context);
1097 int32_t ret = context->GetDelegateTasks().PostAsyncTask(
1098 std::bind(&CoordinationEventManager::OnCoordinationMessage, COOR_EVENT_MGR, msg, ""));
1099 if (ret != RET_OK) {
1100 FI_HILOGE("Posting async task failed");
1101 }
1102 }
1103
NotifyUnchainedResult(const std::string & remoteNetworkId,bool isSuccess)1104 void CoordinationSM::NotifyUnchainedResult(const std::string &remoteNetworkId, bool isSuccess)
1105 {
1106 CALL_DEBUG_ENTER;
1107 FI_HILOGD("Notify unchained result, isSuccess:%{public}d", isSuccess);
1108 if (isSuccess) {
1109 COOR_SM->NotifyChainRemoved();
1110 }
1111 isUnchained_ = false;
1112 isStopping_ = false;
1113 preparedNetworkId_ = std::make_pair("", "");
1114 COOR_SOFTBUS_ADAPTER->CloseInputSoftbus(remoteNetworkId);
1115 }
1116
SetSinkNetworkId(const std::string & sinkNetworkId)1117 void CoordinationSM::SetSinkNetworkId(const std::string &sinkNetworkId)
1118 {
1119 CALL_DEBUG_ENTER;
1120 sinkNetworkId_ = sinkNetworkId;
1121 }
1122
SetPointerVisible()1123 void CoordinationSM::SetPointerVisible()
1124 {
1125 bool hasPointer = COOR_DEV_MGR->HasLocalPointerDevice();
1126 FI_HILOGD("hasPointer:%{public}s", hasPointer ? "true" : "false");
1127 MMI::InputManager::GetInstance()->SetPointerVisible(hasPointer);
1128 }
1129
GetCurrentState()1130 std::shared_ptr<ICoordinationState> CoordinationSM::GetCurrentState()
1131 {
1132 auto it = coordinationStates_.find(currentState_);
1133 if (it == coordinationStates_.end()) {
1134 FI_HILOGE("currentState_ not found");
1135 return nullptr;
1136 }
1137 return it->second;
1138 }
1139
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const1140 bool PointerFilter::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
1141 {
1142 FI_HILOGD("PointerFilter OnInputEvent enter");
1143 CHKPF(pointerEvent);
1144 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
1145 FI_HILOGI("Current event is down");
1146 auto *context = COOR_EVENT_MGR->GetIContext();
1147 CHKPF(context);
1148 int32_t ret = context->GetDelegateTasks().PostAsyncTask(
1149 std::bind(&MMI::InputManager::RemoveInputEventFilter, MMI::InputManager::GetInstance(), filterId_));
1150 if (ret != RET_OK) {
1151 FI_HILOGE("Posting async task failed");
1152 }
1153 filterId_ = -1;
1154 return true;
1155 }
1156 return false;
1157 }
1158 } // namespace DeviceStatus
1159 } // namespace Msdp
1160 } // namespace OHOS
1161