1 /*
2 * Copyright (c) 2023-2025 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 "cooperate_in.h"
17 #include "cooperate_hisysevent.h"
18
19 #include "devicestatus_define.h"
20 #include "utility.h"
21
22 #undef LOG_TAG
23 #define LOG_TAG "CooperateIn"
24
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace Cooperate {
29
CooperateIn(IStateMachine & parent,IContext * env)30 CooperateIn::CooperateIn(IStateMachine &parent, IContext *env)
31 : ICooperateState(parent), env_(env)
32 {
33 initial_ = std::make_shared<Initial>(*this);
34 Initial::BuildChains(initial_, *this);
35 current_ = initial_;
36 }
37
~CooperateIn()38 CooperateIn::~CooperateIn()
39 {
40 Initial::RemoveChains(initial_);
41 }
42
OnEvent(Context & context,const CooperateEvent & event)43 void CooperateIn::OnEvent(Context &context, const CooperateEvent &event)
44 {
45 current_->OnEvent(context, event);
46 }
47
OnEnterState(Context & context)48 void CooperateIn::OnEnterState(Context &context)
49 {
50 CALL_INFO_TRACE;
51 int32_t ret = env_->GetInput().SetPointerVisibility(!context.NeedHideCursor());
52 CooperateRadarInfo radarInfo {
53 .funcName = __FUNCTION__,
54 .bizState = static_cast<int32_t> (BizState::STATE_END),
55 .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_PASSIVE),
56 .hostName = "",
57 .localNetId = "",
58 .peerNetId = ""
59 };
60 if (ret != RET_OK) {
61 radarInfo.bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_CURSOR_VISIBILITY);
62 radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL);
63 radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::PASSIVE_CURSOR_VISIBILITY_FAILED);
64 CooperateRadar::ReportCooperateRadarInfo(radarInfo);
65 }
66 radarInfo.bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_CURSOR_VISIBILITY);
67 radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_SUCCESS);
68 radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::CALLING_COOPERATE_SUCCESS);
69 CooperateRadar::ReportCooperateRadarInfo(radarInfo);
70 }
71
OnLeaveState(Context & context)72 void CooperateIn::OnLeaveState(Context & context)
73 {
74 CALL_INFO_TRACE;
75 UpdateCooperateFlagEvent event {
76 .mask = COOPERATE_FLAG_HIDE_CURSOR,
77 .flag = COOPERATE_FLAG_HIDE_CURSOR,
78 };
79 context.UpdateCooperateFlag(event);
80 CHKPV(env_);
81 env_->GetInput().SetPointerVisibility(false);
82 }
83
84 std::set<int32_t> CooperateIn::Initial::filterPointerActions_ {
85 MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW,
86 MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW,
87 MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW,
88 MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW,
89 };
90
BuildChains(std::shared_ptr<Initial> self,CooperateIn & parent)91 void CooperateIn::Initial::BuildChains(std::shared_ptr<Initial> self, CooperateIn &parent)
92 {
93 auto s11 = std::make_shared<RelayConfirmation>(parent, self);
94 self->relay_ = s11;
95 s11->SetNext(self);
96 }
97
RemoveChains(std::shared_ptr<Initial> self)98 void CooperateIn::Initial::RemoveChains(std::shared_ptr<Initial> self)
99 {
100 if (self->relay_ != nullptr) {
101 self->relay_->SetNext(nullptr);
102 self->relay_ = nullptr;
103 }
104 }
105
Initial(CooperateIn & parent)106 CooperateIn::Initial::Initial(CooperateIn &parent)
107 : ICooperateStep(parent, nullptr), parent_(parent)
108 {
109 AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
110 this->OnDisable(context, event);
111 });
112 AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
113 this->OnStart(context, event);
114 });
115 AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
116 this->OnStop(context, event);
117 });
118 AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
119 this->OnAppClosed(context, event);
120 });
121 AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
122 this->OnPointerEvent(context, event);
123 });
124 AddHandler(CooperateEventType::DDM_BOARD_OFFLINE, [this](Context &context, const CooperateEvent &event) {
125 this->OnBoardOffline(context, event);
126 });
127 AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
128 [this](Context &context, const CooperateEvent &event) {
129 this->OnSwitchChanged(context, event);
130 });
131 AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
132 [this](Context &context, const CooperateEvent &event) {
133 this->OnSoftbusSessionClosed(context, event);
134 });
135 AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
136 [this](Context &context, const CooperateEvent &event) {
137 this->OnRemoteStart(context, event);
138 });
139 AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
140 [this](Context &context, const CooperateEvent &event) {
141 this->OnRemoteStop(context, event);
142 });
143 AddHandler(CooperateEventType::UPDATE_COOPERATE_FLAG,
144 [this](Context &context, const CooperateEvent &event) {
145 this->OnUpdateCooperateFlag(context, event);
146 });
147 AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
148 [this](Context &context, const CooperateEvent &event) {
149 this->OnRemoteInputDevice(context, event);
150 });
151 AddHandler(CooperateEventType::WITH_OPTIONS_START,
152 [this](Context &context, const CooperateEvent &event) {
153 this->OnStartWithOptions(context, event);
154 });
155 AddHandler(CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
156 [this](Context &context, const CooperateEvent &event) {
157 this->OnRemoteStartWithOptions(context, event);
158 });
159 }
160
OnDisable(Context & context,const CooperateEvent & event)161 void CooperateIn::Initial::OnDisable(Context &context, const CooperateEvent &event)
162 {
163 FI_HILOGI("[disable cooperation] Stop cooperation");
164 parent_.StopCooperate(context, event);
165 }
166
OnStart(Context & context,const CooperateEvent & event)167 void CooperateIn::Initial::OnStart(Context &context, const CooperateEvent &event)
168 {
169 CALL_INFO_TRACE;
170 StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
171 context.ResetPriv();
172
173 if (parent_.env_->GetDragManager().GetDragState() == DragState::MOTION_DRAGGING) {
174 FI_HILOGE("Not allow cooperate");
175 NotAollowCooperateWhenMotionDragging result {
176 .pid = startEvent.pid,
177 .userData = startEvent.userData,
178 .networkId = startEvent.remoteNetworkId,
179 .success = false,
180 .errCode = static_cast<int32_t>(CoordinationErrCode::NOT_AOLLOW_COOPERATE_WHEN_MOTION_DRAGGING)
181 };
182 context.eventMgr_.ErrorNotAollowCooperateWhenMotionDragging(result);
183 return;
184 }
185 if (context.IsLocal(startEvent.remoteNetworkId)) {
186 DSoftbusStartCooperateFinished result {
187 .success = false,
188 .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
189 };
190 context.eventMgr_.StartCooperateFinish(result);
191 return;
192 }
193 FI_HILOGI("[start] start cooperation(%{public}s, %{public}d)",
194 Utility::Anonymize(startEvent.remoteNetworkId).c_str(), startEvent.startDeviceId);
195 context.eventMgr_.StartCooperate(startEvent);
196
197 if (context.IsPeer(startEvent.remoteNetworkId)) {
198 OnComeBack(context, event);
199 } else {
200 OnRelay(context, event);
201 }
202 }
203
OnComeBack(Context & context,const CooperateEvent & event)204 void CooperateIn::Initial::OnComeBack(Context &context, const CooperateEvent &event)
205 {
206 CALL_INFO_TRACE;
207 context.inputEventBuilder_.Disable();
208 FI_HILOGI("[come back] To \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
209 DSoftbusComeBack notice {
210 .originNetworkId = context.Local(),
211 .success = true,
212 .cursorPos = context.NormalizedCursorPosition(),
213 };
214 context.OnStartCooperate(notice.extra);
215 if (context.dsoftbus_.ComeBack(context.Peer(), notice) != RET_OK) {
216 notice.success = false;
217 notice.errCode = static_cast<int32_t>(CoordinationErrCode::SEND_PACKET_FAILED);
218 }
219 context.eventMgr_.StartCooperateFinish(notice);
220 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
221 context.OnBack();
222 }
223
OnRelay(Context & context,const CooperateEvent & event)224 void CooperateIn::Initial::OnRelay(Context &context, const CooperateEvent &event)
225 {
226 CALL_INFO_TRACE;
227 StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
228 parent_.process_.StartCooperate(context, startEvent);
229 FI_HILOGI("[relay cooperate] To \'%{public}s\'", Utility::Anonymize(parent_.process_.Peer()).c_str());
230
231 if (relay_ != nullptr) {
232 Switch(relay_);
233 relay_->OnProgress(context, event);
234 }
235 }
236
OnRelayWithOptions(Context & context,const CooperateEvent & event)237 void CooperateIn::Initial::OnRelayWithOptions(Context &context, const CooperateEvent &event)
238 {
239 CALL_INFO_TRACE;
240 StartWithOptionsEvent startEvent = std::get<StartWithOptionsEvent>(event.event);
241 parent_.process_.StartCooperateWithOptions(context, startEvent);
242 FI_HILOGI("[relay cooperate With Options] To '%{public}s'", Utility::Anonymize(parent_.process_.Peer()).c_str());
243 if (relay_ != nullptr) {
244 Switch(relay_);
245 relay_->OnProgressWithOptions(context, event);
246 }
247 FI_HILOGE("relay_ is nullptr");
248 }
249
OnStartWithOptions(Context & context,const CooperateEvent & event)250 void CooperateIn::Initial::OnStartWithOptions(Context &context, const CooperateEvent &event)
251 {
252 CALL_INFO_TRACE;
253 StartWithOptionsEvent startEvent = std::get<StartWithOptionsEvent>(event.event);
254 context.ResetPriv();
255 if (context.IsLocal(startEvent.remoteNetworkId)) {
256 DSoftbusCooperateWithOptionsFinished result {
257 .success = false,
258 .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
259 };
260 context.eventMgr_.StartCooperateWithOptinsFinish(result);
261 return;
262 }
263 FI_HILOGI("[start] with options start cooperation(%{public}s, %{public}d)",
264 Utility::Anonymize(startEvent.remoteNetworkId).c_str(), startEvent.startDeviceId);
265 context.eventMgr_.StartCooperateWithOptions(startEvent);
266 if (context.IsPeer(startEvent.remoteNetworkId)) {
267 OnComeBackWithOptions(context, event);
268 } else {
269 OnRelayWithOptions(context, event);
270 }
271 }
272
OnComeBackWithOptions(Context & context,const CooperateEvent & event)273 void CooperateIn::Initial::OnComeBackWithOptions(Context &context, const CooperateEvent &event)
274 {
275 CALL_INFO_TRACE;
276 context.inputEventBuilder_.Disable();
277 FI_HILOGI("[come back] To \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
278 StartWithOptionsEvent withOptionsNotice = std::get<StartWithOptionsEvent>(event.event);
279 DSoftbusComeBackWithOptions notice {
280 .originNetworkId = context.Local(),
281 .success = true,
282 .cooperateOptions = {withOptionsNotice.displayX, withOptionsNotice.displayY, withOptionsNotice.displayId},
283 };
284 context.OnStartCooperate(notice.extra);
285 if (context.dsoftbus_.ComeBackWithOptions(context.Peer(), notice) != RET_OK) {
286 notice.success = false;
287 notice.errCode = static_cast<int32_t>(CoordinationErrCode::SEND_PACKET_FAILED);
288 }
289 context.eventMgr_.StartCooperateWithOptinsFinish(notice);
290 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
291 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
292 context.OnBack();
293 }
294
OnStop(Context & context,const CooperateEvent & event)295 void CooperateIn::Initial::OnStop(Context &context, const CooperateEvent &event)
296 {
297 CALL_INFO_TRACE;
298 StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
299
300 context.eventMgr_.StopCooperate(param);
301 parent_.StopCooperate(context, event);
302
303 param.networkId = context.Peer();
304 DSoftbusStopCooperateFinished notice {
305 .networkId = context.Peer(),
306 .normal = true,
307 };
308 context.eventMgr_.StopCooperateFinish(notice);
309
310 parent_.UnchainConnections(context, param);
311 }
312
OnRemoteStart(Context & context,const CooperateEvent & event)313 void CooperateIn::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
314 {
315 CALL_INFO_TRACE;
316 DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
317 context.StorePeerPointerSpeed(notice.pointerSpeed);
318 context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
319 if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
320 return;
321 }
322 context.OnResetCooperation();
323 context.OnRemoteStartCooperate(notice.extra);
324 context.eventMgr_.RemoteStart(notice);
325
326 DSoftbusStopCooperate stopNotice {};
327 context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
328
329 context.RemoteStartSuccess(notice);
330 context.inputEventBuilder_.Update(context);
331 context.eventMgr_.RemoteStartFinish(notice);
332 FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
333 context.OnTransitionIn();
334 }
335
OnRemoteStartWithOptions(Context & context,const CooperateEvent & event)336 void CooperateIn::Initial::OnRemoteStartWithOptions(Context &context, const CooperateEvent &event)
337 {
338 CALL_INFO_TRACE;
339 DSoftbusCooperateOptions notice = std::get<DSoftbusCooperateOptions>(event.event);
340
341 if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
342 return;
343 }
344 context.OnResetCooperation();
345 context.OnRemoteStartCooperate(notice.extra);
346 context.eventMgr_.RemoteStartWithOptions(notice);
347
348 DSoftbusStopCooperate stopNotice {};
349 context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
350
351 context.OnRemoteStart(notice);
352 context.inputEventBuilder_.Update(context);
353 context.eventMgr_.RemoteStartWithOptionsFinish(notice);
354 FI_HILOGI("[remote start cooperate with options] Cooperation with \'%{public}s\' established",
355 Utility::Anonymize(context.Peer()).c_str());
356 context.OnTransitionIn();
357 }
358
OnRemoteStop(Context & context,const CooperateEvent & event)359 void CooperateIn::Initial::OnRemoteStop(Context &context, const CooperateEvent &event)
360 {
361 DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
362
363 if (!context.IsPeer(notice.networkId)) {
364 return;
365 }
366 FI_HILOGI("[remote stop] Notification from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
367 context.eventMgr_.RemoteStop(notice);
368 context.inputEventBuilder_.Disable();
369 context.eventMgr_.RemoteStopFinish(notice);
370 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
371 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
372 context.OnResetCooperation();
373 }
374
OnAppClosed(Context & context,const CooperateEvent & event)375 void CooperateIn::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
376 {
377 FI_HILOGI("[app closed] Close all connections");
378 context.dsoftbus_.CloseAllSessions();
379 FI_HILOGI("[app closed] Stop cooperation");
380 parent_.StopCooperate(context, event);
381 }
382
OnPointerEvent(Context & context,const CooperateEvent & event)383 void CooperateIn::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
384 {
385 InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
386
387 if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
388 (filterPointerActions_.find(notice.pointerAction) != filterPointerActions_.end()) ||
389 !InputEventBuilder::IsLocalEvent(notice)) {
390 return;
391 }
392 FI_HILOGI("Stop cooperation on operation of local pointer");
393 context.OnPointerEvent(notice);
394 parent_.StopCooperate(context, event);
395 }
396
OnBoardOffline(Context & context,const CooperateEvent & event)397 void CooperateIn::Initial::OnBoardOffline(Context &context, const CooperateEvent &event)
398 {
399 DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
400
401 if (!context.IsPeer(notice.networkId)) {
402 return;
403 }
404 FI_HILOGI("[board offline] Peer(\'%{public}s\') is offline", Utility::Anonymize(notice.networkId).c_str());
405 parent_.StopCooperate(context, event);
406 }
407
OnSwitchChanged(Context & context,const CooperateEvent & event)408 void CooperateIn::Initial::OnSwitchChanged(Context &context, const CooperateEvent &event)
409 {
410 DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
411
412 if (!context.IsPeer(notice.networkId) || notice.normal) {
413 return;
414 }
415 FI_HILOGI("[switch off] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
416 parent_.StopCooperate(context, event);
417 }
418
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)419 void CooperateIn::Initial::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
420 {
421 DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
422
423 if (!context.IsPeer(notice.networkId)) {
424 return;
425 }
426 FI_HILOGI("[softbus session closed] Disconnected with \'%{public}s\'",
427 Utility::Anonymize(notice.networkId).c_str());
428 parent_.StopCooperate(context, event);
429 context.eventMgr_.OnSoftbusSessionClosed(notice);
430 }
431
OnRemoteInputDevice(Context & context,const CooperateEvent & event)432 void CooperateIn::Initial::OnRemoteInputDevice(Context &context, const CooperateEvent &event)
433 {
434 CALL_INFO_TRACE;
435 DSoftbusSyncInputDevice notice = std::get<DSoftbusSyncInputDevice>(event.event);
436 if (!context.IsPeer(notice.networkId)) {
437 return;
438 }
439 FI_HILOGI("Remote input device from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
440 context.inputDevMgr_.AddVirtualInputDevice(notice.networkId);
441 }
442
OnRemoteHotPlug(Context & context,const CooperateEvent & event)443 void CooperateIn::Initial::OnRemoteHotPlug(Context &context, const CooperateEvent &event)
444 {
445 DSoftbusHotPlugEvent notice = std::get<DSoftbusHotPlugEvent>(event.event);
446 if (!context.IsPeer(notice.networkId)) {
447 return;
448 }
449 FI_HILOGI("Remote hot plug event from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
450 }
451
OnUpdateCooperateFlag(Context & context,const CooperateEvent & event)452 void CooperateIn::Initial::OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)
453 {
454 UpdateCooperateFlagEvent notice = std::get<UpdateCooperateFlagEvent>(event.event);
455 uint32_t changed = (notice.mask & (context.CooperateFlag() ^ notice.flag));
456 context.UpdateCooperateFlag(notice);
457
458 if (changed & COOPERATE_FLAG_FREEZE_CURSOR) {
459 FI_HILOGI("Toggle freezing state of cursor");
460 if (notice.flag & COOPERATE_FLAG_FREEZE_CURSOR) {
461 context.inputEventBuilder_.Freeze();
462 } else {
463 context.inputEventBuilder_.Thaw();
464 }
465 }
466 }
467
OnProgress(Context & context,const CooperateEvent & event)468 void CooperateIn::Initial::OnProgress(Context &context, const CooperateEvent &event)
469 {}
470
OnReset(Context & context,const CooperateEvent & event)471 void CooperateIn::Initial::OnReset(Context &context, const CooperateEvent &event)
472 {}
473
OnProgressWithOptions(Context & context,const CooperateEvent & event)474 void CooperateIn::Initial::OnProgressWithOptions(Context &context, const CooperateEvent &event)
475 {}
476
RelayConfirmation(CooperateIn & parent,std::shared_ptr<ICooperateStep> prev)477 CooperateIn::RelayConfirmation::RelayConfirmation(CooperateIn &parent, std::shared_ptr<ICooperateStep> prev)
478 : ICooperateStep(parent, prev), parent_(parent)
479 {
480 AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
481 this->OnDisable(context, event);
482 });
483 AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
484 this->OnStop(context, event);
485 });
486 AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
487 this->OnAppClosed(context, event);
488 });
489 AddHandler(CooperateEventType::INPUT_POINTER_EVENT,
490 [this](Context &context, const CooperateEvent &event) {
491 this->OnPointerEvent(context, event);
492 });
493 AddHandler(CooperateEventType::DDM_BOARD_OFFLINE,
494 [this](Context &context, const CooperateEvent &event) {
495 this->OnBoardOffline(context, event);
496 });
497 AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
498 [this](Context &context, const CooperateEvent &event) {
499 this->OnSwitchChanged(context, event);
500 });
501 AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
502 [this](Context &context, const CooperateEvent &event) {
503 this->OnSoftbusSessionClosed(context, event);
504 });
505 AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
506 [this](Context &context, const CooperateEvent &event) {
507 this->OnResponse(context, event);
508 });
509 AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
510 [this](Context &context, const CooperateEvent &event) {
511 this->OnRemoteStart(context, event);
512 });
513 AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
514 [this](Context &context, const CooperateEvent &event) {
515 this->OnRemoteStop(context, event);
516 });
517 AddHandler(CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
518 [this](Context &context, const CooperateEvent &event) {
519 this->OnRemoteStartWithOptions(context, event);
520 });
521 AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS_FINISHED,
522 [this](Context &context, const CooperateEvent &event) {
523 this->OnResponseWithOptions(context, event);
524 });
525 }
526
OnDisable(Context & context,const CooperateEvent & event)527 void CooperateIn::RelayConfirmation::OnDisable(Context &context, const CooperateEvent &event)
528 {
529 FI_HILOGI("[relay cooperate] Disable cooperation");
530 parent_.StopCooperate(context, event);
531 OnReset(context, event);
532 }
533
OnStop(Context & context,const CooperateEvent & event)534 void CooperateIn::RelayConfirmation::OnStop(Context &context, const CooperateEvent &event)
535 {
536 FI_HILOGI("[relay cooperate] Stop cooperation");
537 parent_.StopCooperate(context, event);
538 OnReset(context, event);
539
540 StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
541 parent_.UnchainConnections(context, param);
542 }
543
OnRemoteStart(Context & context,const CooperateEvent & event)544 void CooperateIn::RelayConfirmation::OnRemoteStart(Context &context, const CooperateEvent &event)
545 {
546 CALL_INFO_TRACE;
547 DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
548 context.StorePeerPointerSpeed(notice.pointerSpeed);
549 context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
550 if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
551 return;
552 }
553 FI_HILOGI("[remote start] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
554 if (parent_.process_.IsPeer(notice.networkId)) {
555 auto ret = context.Sender().Send(event);
556 if (ret != Channel<CooperateEvent>::NO_ERROR) {
557 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
558 }
559 OnResetWithNotifyMessage(context, event);
560 return;
561 }
562 parent_.env_->GetTimerManager().AddTimer(DEFAULT_COOLING_TIME, REPEAT_ONCE,
563 [sender = context.Sender(), event]() mutable {
564 auto ret = sender.Send(event);
565 if (ret != Channel<CooperateEvent>::NO_ERROR) {
566 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
567 }
568 });
569 }
570
OnRemoteStartWithOptions(Context & context,const CooperateEvent & event)571 void CooperateIn::RelayConfirmation::OnRemoteStartWithOptions(Context &context, const CooperateEvent &event)
572 {
573 CALL_INFO_TRACE;
574 DSoftbusCooperateOptions notice = std::get<DSoftbusCooperateOptions>(event.event);
575
576 if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
577 return;
578 }
579 FI_HILOGI("[remote start] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
580 if (parent_.process_.IsPeer(notice.networkId)) {
581 auto ret = context.Sender().Send(event);
582 if (ret != Channel<CooperateEvent>::NO_ERROR) {
583 FI_HILOGE("Failed to send with options event via channel, error:%{public}d", ret);
584 }
585 OnReset(context, event);
586 return;
587 }
588 parent_.env_->GetTimerManager().AddTimer(DEFAULT_COOLING_TIME, REPEAT_ONCE,
589 [sender = context.Sender(), event]() mutable {
590 auto ret = sender.Send(event);
591 if (ret != Channel<CooperateEvent>::NO_ERROR) {
592 FI_HILOGE("Failed to send with options event via channel, error:%{public}d", ret);
593 }
594 });
595 }
596
OnRemoteStop(Context & context,const CooperateEvent & event)597 void CooperateIn::RelayConfirmation::OnRemoteStop(Context &context, const CooperateEvent &event)
598 {
599 DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
600
601 if (!context.IsPeer(notice.networkId)) {
602 return;
603 }
604 FI_HILOGI("[remote stop] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
605 auto ret = context.Sender().Send(event);
606 if (ret != Channel<CooperateEvent>::NO_ERROR) {
607 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
608 }
609 OnReset(context, event);
610 }
611
OnAppClosed(Context & context,const CooperateEvent & event)612 void CooperateIn::RelayConfirmation::OnAppClosed(Context &context, const CooperateEvent &event)
613 {
614 FI_HILOGI("[app closed] Close all connections");
615 context.dsoftbus_.CloseAllSessions();
616 FI_HILOGI("[relay cooperate] Stop cooperation on app closed");
617 parent_.StopCooperate(context, event);
618 OnResetWithNotifyMessage(context, event);
619 }
620
OnPointerEvent(Context & context,const CooperateEvent & event)621 void CooperateIn::RelayConfirmation::OnPointerEvent(Context &context, const CooperateEvent &event)
622 {
623 InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
624
625 if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
626 !InputEventBuilder::IsLocalEvent(notice)) {
627 return;
628 }
629 FI_HILOGI("[relay cooperate] Stop cooperation on operation of local pointer");
630 context.OnPointerEvent(notice);
631 parent_.StopCooperate(context, event);
632 OnReset(context, event);
633 }
634
OnBoardOffline(Context & context,const CooperateEvent & event)635 void CooperateIn::RelayConfirmation::OnBoardOffline(Context &context, const CooperateEvent &event)
636 {
637 DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
638
639 if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
640 return;
641 }
642 FI_HILOGI("[relay cooperate] Peer(%{public}s) is offline", Utility::Anonymize(notice.networkId).c_str());
643 if (context.IsPeer(notice.networkId)) {
644 parent_.StopCooperate(context, event);
645 }
646 OnResetWithNotifyMessage(context, event);
647 }
648
OnSwitchChanged(Context & context,const CooperateEvent & event)649 void CooperateIn::RelayConfirmation::OnSwitchChanged(Context &context, const CooperateEvent &event)
650 {
651 DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
652
653 if (notice.normal ||
654 (!context.IsPeer(notice.networkId) &&
655 !parent_.process_.IsPeer(notice.networkId))) {
656 return;
657 }
658 FI_HILOGI("[relay cooperate] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
659 if (context.IsPeer(notice.networkId)) {
660 parent_.StopCooperate(context, event);
661 }
662 OnResetWithNotifyMessage(context, event);
663 }
664
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)665 void CooperateIn::RelayConfirmation::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
666 {
667 DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
668
669 if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
670 return;
671 }
672 FI_HILOGI("[relay cooperate] Disconnected with \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
673 if (context.IsPeer(notice.networkId)) {
674 parent_.StopCooperate(context, event);
675 }
676 OnResetWithNotifyMessage(context, event);
677 }
678
OnResponse(Context & context,const CooperateEvent & event)679 void CooperateIn::RelayConfirmation::OnResponse(Context &context, const CooperateEvent &event)
680 {
681 DSoftbusRelayCooperateFinished notice = std::get<DSoftbusRelayCooperateFinished>(event.event);
682
683 if (!context.IsPeer(notice.networkId)) {
684 return;
685 }
686 FI_HILOGI("[relay cooperate] \'%{public}s\' respond", Utility::Anonymize(notice.networkId).c_str());
687 parent_.env_->GetTimerManager().RemoveTimer(timerId_);
688 if (notice.normal) {
689 OnNormal(context, event);
690 Proceed(context, event);
691 } else {
692 OnResetWithNotifyMessage(context, event);
693 parent_.StopCooperate(context, event);
694 }
695 }
696
OnResponseWithOptions(Context & context,const CooperateEvent & event)697 void CooperateIn::RelayConfirmation::OnResponseWithOptions(Context &context, const CooperateEvent &event)
698 {
699 DSoftbusRelayCooperateFinished notice = std::get<DSoftbusRelayCooperateFinished>(event.event);
700 if (!context.IsPeer(notice.networkId)) {
701 return;
702 }
703 FI_HILOGI("[relay cooperate] \'%{public}s\' respond", Utility::Anonymize(notice.networkId).c_str());
704 parent_.env_->GetTimerManager().RemoveTimer(timerId_);
705 if (notice.normal) {
706 OnNormalWithOptions(context, event);
707 Proceed(context, event);
708 } else {
709 OnResetWithOptionsNotifyMessage(context, event);
710 }
711 }
712
OnNormal(Context & context,const CooperateEvent & event)713 void CooperateIn::RelayConfirmation::OnNormal(Context &context, const CooperateEvent &event)
714 {
715 FI_HILOGI("[relay cooperate] Cooperation with \'%{public}s\' established",
716 Utility::Anonymize(parent_.process_.Peer()).c_str());
717 context.inputEventBuilder_.Disable();
718
719 DSoftbusStartCooperate notice {
720 .originNetworkId = context.Peer(),
721 .success = true,
722 .cursorPos = context.NormalizedCursorPosition(),
723 };
724 context.OnStartCooperate(notice.extra);
725 context.dsoftbus_.StartCooperate(parent_.process_.Peer(), notice);
726
727 context.eventMgr_.StartCooperateFinish(notice);
728 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
729 context.OnRelayCooperation(parent_.process_.Peer(), context.NormalizedCursorPosition());
730 }
731
OnNormalWithOptions(Context & context,const CooperateEvent & event)732 void CooperateIn::RelayConfirmation::OnNormalWithOptions(Context &context, const CooperateEvent &event)
733 {
734 FI_HILOGI("[relay cooperate] Cooperation with \'%{public}s\' established",
735 Utility::Anonymize(parent_.process_.Peer()).c_str());
736 context.inputEventBuilder_.Disable();
737
738 DSoftbusCooperateOptions notice {
739 .originNetworkId = context.Peer(),
740 .success = true,
741 .cooperateOptions = {startWithOptionsEvent_.displayX, startWithOptionsEvent_.displayY,
742 startWithOptionsEvent_.displayId},
743 };
744 context.OnStartCooperate(notice.extra);
745 context.dsoftbus_.StartCooperateWithOptions(parent_.process_.Peer(), notice);
746
747 context.eventMgr_.StartCooperateWithOptinsFinish(notice);
748 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
749 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
750 context.OnRelayCooperation(parent_.process_.Peer(), context.NormalizedCursorPosition());
751 }
752
OnProgress(Context & context,const CooperateEvent & event)753 void CooperateIn::RelayConfirmation::OnProgress(Context &context, const CooperateEvent &event)
754 {
755 std::string remoteNetworkId = parent_.process_.Peer();
756 FI_HILOGI("[relay cooperate] Connect \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
757 int32_t ret = context.dsoftbus_.OpenSession(remoteNetworkId);
758 if (ret != RET_OK) {
759 FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
760 OnResetWithNotifyMessage(context, event);
761 return;
762 }
763
764 FI_HILOGI("[relay cooperate] Notify origin(\'%{public}s\')", Utility::Anonymize(context.Peer()).c_str());
765 DSoftbusRelayCooperate notice {
766 .targetNetworkId = parent_.process_.Peer(),
767 .pointerSpeed = context.GetPointerSpeed(),
768 .touchPadSpeed = context.GetTouchPadSpeed(),
769 };
770 context.dsoftbus_.RelayCooperate(context.Peer(), notice);
771 timerId_ = parent_.env_->GetTimerManager().AddTimer(DEFAULT_TIMEOUT, REPEAT_ONCE,
772 [sender = context.Sender(), remoteNetworkId = context.Peer()]() mutable {
773 auto ret = sender.Send(CooperateEvent(
774 CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
775 DSoftbusRelayCooperateFinished {
776 .networkId = remoteNetworkId,
777 .normal = false,
778 }));
779 if (ret != Channel<CooperateEvent>::NO_ERROR) {
780 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
781 }
782 });
783 }
784
OnProgressWithOptions(Context & context,const CooperateEvent & event)785 void CooperateIn::RelayConfirmation::OnProgressWithOptions(Context &context, const CooperateEvent &event)
786 {
787 std::string remoteNetworkId = parent_.process_.Peer();
788 FI_HILOGI("[relay cooperate] Connect \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
789 int32_t ret = context.dsoftbus_.OpenSession(remoteNetworkId);
790 if (ret != RET_OK) {
791 FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
792 OnResetWithOptionsNotifyMessage(context, event);
793 return;
794 }
795
796 FI_HILOGI("[relay cooperate] Notify origin(\'%{public}s\')", Utility::Anonymize(context.Peer()).c_str());
797 DSoftbusRelayCooperate notice {
798 .targetNetworkId = parent_.process_.Peer(),
799 .pointerSpeed = context.GetPointerSpeed(),
800 .touchPadSpeed = context.GetTouchPadSpeed(),
801 };
802 context.dsoftbus_.RelayCooperateWithOptions(context.Peer(), notice);
803 StartWithOptionsEvent startEvent = std::get<StartWithOptionsEvent>(event.event);
804 startWithOptionsEvent_.displayX = startEvent.displayX;
805 startWithOptionsEvent_.displayY = startEvent.displayY;
806 startWithOptionsEvent_.displayId = startEvent.displayId;
807 timerId_ = parent_.env_->GetTimerManager().AddTimer(DEFAULT_TIMEOUT, REPEAT_ONCE,
808 [sender = context.Sender(), remoteNetworkId = context.Peer()]() mutable {
809 auto ret = sender.Send(CooperateEvent(
810 CooperateEventType::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS_FINISHED,
811 DSoftbusRelayCooperateFinished {
812 .networkId = remoteNetworkId,
813 .normal = false,
814 }));
815 if (ret != Channel<CooperateEvent>::NO_ERROR) {
816 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
817 }
818 });
819 }
820
OnReset(Context & context,const CooperateEvent & event)821 void CooperateIn::RelayConfirmation::OnReset(Context &context, const CooperateEvent &event)
822 {
823 FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
824 Utility::Anonymize(parent_.process_.Peer()).c_str());
825 Reset(context, event);
826 }
827
OnResetWithNotifyMessage(Context & context,const CooperateEvent & event)828 void CooperateIn::RelayConfirmation::OnResetWithNotifyMessage(Context &context, const CooperateEvent &event)
829 {
830 FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
831 Utility::Anonymize(parent_.process_.Peer()).c_str());
832 DSoftbusStartCooperateFinished result {
833 .success = false
834 };
835 context.eventMgr_.StartCooperateFinish(result);
836 Reset(context, event);
837 }
838
OnResetWithOptionsNotifyMessage(Context & context,const CooperateEvent & event)839 void CooperateIn::RelayConfirmation::OnResetWithOptionsNotifyMessage(Context &context, const CooperateEvent &event)
840 {
841 FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
842 Utility::Anonymize(parent_.process_.Peer()).c_str());
843 DSoftbusCooperateWithOptionsFinished result {
844 .success = false
845 };
846 context.eventMgr_.StartCooperateWithOptinsFinish(result);
847 Reset(context, event);
848 }
849
StopCooperate(Context & context,const CooperateEvent & event)850 void CooperateIn::StopCooperate(Context &context, const CooperateEvent &event)
851 {
852 FI_HILOGI("Stop cooperation with \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
853 context.inputEventBuilder_.Disable();
854 context.UpdateCursorPosition();
855
856 DSoftbusStopCooperate notice {};
857 context.dsoftbus_.StopCooperate(context.Peer(), notice);
858 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
859 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
860 context.OnResetCooperation();
861 SetPointerVisible(context);
862 }
863
SetPointerVisible(Context & context)864 void CooperateIn::SetPointerVisible(Context &context)
865 {
866 CHKPV(env_);
867 bool hasLocalPointerDevice = env_->GetDeviceManager().HasLocalPointerDevice() ||
868 env_->GetInput().HasLocalPointerDevice();
869 FI_HILOGI("HasLocalPointerDevice:%{public}s", hasLocalPointerDevice ? "true" : "false");
870 env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
871 }
872
UnchainConnections(Context & context,const StopCooperateEvent & event) const873 void CooperateIn::UnchainConnections(Context &context, const StopCooperateEvent &event) const
874 {
875 if (event.isUnchained) {
876 FI_HILOGI("Unchain all connections");
877 context.dsoftbus_.CloseAllSessions();
878 context.eventMgr_.OnUnchain(event);
879 }
880 }
881 } // namespace Cooperate
882 } // namespace DeviceStatus
883 } // namespace Msdp
884 } // namespace OHOS
885