• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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