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