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