1 /*
2 * Copyright (c) 2023-2024 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
18 #include "devicestatus_define.h"
19 #include "utility.h"
20
21 #undef LOG_TAG
22 #define LOG_TAG "CooperateIn"
23
24 namespace OHOS {
25 namespace Msdp {
26 namespace DeviceStatus {
27 namespace Cooperate {
28
CooperateIn(IStateMachine &parent, IContext *env)29 CooperateIn::CooperateIn(IStateMachine &parent, IContext *env)
30 : ICooperateState(parent), env_(env)
31 {
32 initial_ = std::make_shared<Initial>(*this);
33 Initial::BuildChains(initial_, *this);
34 current_ = initial_;
35 }
36
~CooperateIn()37 CooperateIn::~CooperateIn()
38 {
39 Initial::RemoveChains(initial_);
40 }
41
OnEvent(Context &context, const CooperateEvent &event)42 void CooperateIn::OnEvent(Context &context, const CooperateEvent &event)
43 {
44 current_->OnEvent(context, event);
45 }
46
OnEnterState(Context &context)47 void CooperateIn::OnEnterState(Context &context)
48 {
49 CALL_INFO_TRACE;
50 env_->GetInput().SetPointerVisibility(!context.NeedHideCursor());
51 }
52
OnLeaveState(Context & context)53 void CooperateIn::OnLeaveState(Context & context)
54 {
55 CALL_INFO_TRACE;
56 UpdateCooperateFlagEvent event {
57 .mask = COOPERATE_FLAG_HIDE_CURSOR,
58 .flag = COOPERATE_FLAG_HIDE_CURSOR,
59 };
60 context.UpdateCooperateFlag(event);
61 CHKPV(env_);
62 env_->GetInput().SetPointerVisibility(false);
63 }
64
65 std::set<int32_t> CooperateIn::Initial::filterPointerActions_ {
66 MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW,
67 MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW,
68 MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW,
69 MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW,
70 };
71
BuildChains(std::shared_ptr<Initial> self, CooperateIn &parent)72 void CooperateIn::Initial::BuildChains(std::shared_ptr<Initial> self, CooperateIn &parent)
73 {
74 auto s11 = std::make_shared<RelayConfirmation>(parent, self);
75 self->relay_ = s11;
76 s11->SetNext(self);
77 }
78
RemoveChains(std::shared_ptr<Initial> self)79 void CooperateIn::Initial::RemoveChains(std::shared_ptr<Initial> self)
80 {
81 if (self->relay_ != nullptr) {
82 self->relay_->SetNext(nullptr);
83 self->relay_ = nullptr;
84 }
85 }
86
Initial(CooperateIn &parent)87 CooperateIn::Initial::Initial(CooperateIn &parent)
88 : ICooperateStep(parent, nullptr), parent_(parent)
89 {
90 AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
91 this->OnDisable(context, event);
92 });
93 AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
94 this->OnStart(context, event);
95 });
96 AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
97 this->OnStop(context, event);
98 });
99 AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
100 this->OnAppClosed(context, event);
101 });
102 AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
103 this->OnPointerEvent(context, event);
104 });
105 AddHandler(CooperateEventType::DDM_BOARD_OFFLINE, [this](Context &context, const CooperateEvent &event) {
106 this->OnBoardOffline(context, event);
107 });
108 AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
109 [this](Context &context, const CooperateEvent &event) {
110 this->OnSwitchChanged(context, event);
111 });
112 AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
113 [this](Context &context, const CooperateEvent &event) {
114 this->OnSoftbusSessionClosed(context, event);
115 });
116 AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
117 [this](Context &context, const CooperateEvent &event) {
118 this->OnRemoteStart(context, event);
119 });
120 AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
121 [this](Context &context, const CooperateEvent &event) {
122 this->OnRemoteStop(context, event);
123 });
124 AddHandler(CooperateEventType::UPDATE_COOPERATE_FLAG,
125 [this](Context &context, const CooperateEvent &event) {
126 this->OnUpdateCooperateFlag(context, event);
127 });
128 AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
129 [this](Context &context, const CooperateEvent &event) {
130 this->OnRemoteInputDevice(context, event);
131 });
132 }
133
OnDisable(Context &context, const CooperateEvent &event)134 void CooperateIn::Initial::OnDisable(Context &context, const CooperateEvent &event)
135 {
136 FI_HILOGI("[disable cooperation] Stop cooperation");
137 parent_.StopCooperate(context, event);
138 }
139
OnStart(Context &context, const CooperateEvent &event)140 void CooperateIn::Initial::OnStart(Context &context, const CooperateEvent &event)
141 {
142 CALL_INFO_TRACE;
143 StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
144
145 if (context.IsLocal(startEvent.remoteNetworkId)) {
146 DSoftbusStartCooperateFinished result {
147 .success = false,
148 .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
149 };
150 context.eventMgr_.StartCooperateFinish(result);
151 return;
152 }
153 FI_HILOGI("[start] start cooperation(%{public}s, %{public}d)",
154 Utility::Anonymize(startEvent.remoteNetworkId).c_str(), startEvent.startDeviceId);
155 context.eventMgr_.StartCooperate(startEvent);
156
157 if (context.IsPeer(startEvent.remoteNetworkId)) {
158 OnComeBack(context, event);
159 } else {
160 OnRelay(context, event);
161 }
162 }
163
OnComeBack(Context &context, const CooperateEvent &event)164 void CooperateIn::Initial::OnComeBack(Context &context, const CooperateEvent &event)
165 {
166 CALL_INFO_TRACE;
167 context.inputEventBuilder_.Disable();
168 FI_HILOGI("[come back] To \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
169 DSoftbusComeBack notice {
170 .originNetworkId = context.Local(),
171 .success = true,
172 .cursorPos = context.NormalizedCursorPosition(),
173 };
174 context.OnStartCooperate(notice.extra);
175 if (context.dsoftbus_.ComeBack(context.Peer(), notice) != RET_OK) {
176 notice.success = false;
177 notice.errCode = static_cast<int32_t>(CoordinationErrCode::SEND_PACKET_FAILED);
178 }
179 context.eventMgr_.StartCooperateFinish(notice);
180 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
181 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
182 context.OnBack();
183 }
184
OnRelay(Context &context, const CooperateEvent &event)185 void CooperateIn::Initial::OnRelay(Context &context, const CooperateEvent &event)
186 {
187 CALL_INFO_TRACE;
188 StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
189 parent_.process_.StartCooperate(context, startEvent);
190 FI_HILOGI("[relay cooperate] To \'%{public}s\'", Utility::Anonymize(parent_.process_.Peer()).c_str());
191
192 if (relay_ != nullptr) {
193 Switch(relay_);
194 relay_->OnProgress(context, event);
195 }
196 }
197
OnStop(Context &context, const CooperateEvent &event)198 void CooperateIn::Initial::OnStop(Context &context, const CooperateEvent &event)
199 {
200 CALL_INFO_TRACE;
201 StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
202
203 context.eventMgr_.StopCooperate(param);
204 parent_.StopCooperate(context, event);
205
206 param.networkId = context.Peer();
207 DSoftbusStopCooperateFinished notice {
208 .networkId = context.Peer(),
209 .normal = true,
210 };
211 context.eventMgr_.StopCooperateFinish(notice);
212
213 parent_.UnchainConnections(context, param);
214 }
215
OnRemoteStart(Context &context, const CooperateEvent &event)216 void CooperateIn::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
217 {
218 CALL_INFO_TRACE;
219 DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
220
221 if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
222 return;
223 }
224 context.OnResetCooperation();
225 context.OnRemoteStartCooperate(notice.extra);
226 context.eventMgr_.RemoteStart(notice);
227
228 DSoftbusStopCooperate stopNotice {};
229 context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
230
231 context.RemoteStartSuccess(notice);
232 context.inputEventBuilder_.Update(context);
233 context.eventMgr_.RemoteStartFinish(notice);
234 FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
235 context.OnTransitionIn();
236 }
237
OnRemoteStop(Context &context, const CooperateEvent &event)238 void CooperateIn::Initial::OnRemoteStop(Context &context, const CooperateEvent &event)
239 {
240 DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
241
242 if (!context.IsPeer(notice.networkId)) {
243 return;
244 }
245 FI_HILOGI("[remote stop] Notification from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
246 context.eventMgr_.RemoteStop(notice);
247 context.inputEventBuilder_.Disable();
248 context.eventMgr_.RemoteStopFinish(notice);
249 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
250 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
251 context.OnResetCooperation();
252 }
253
OnAppClosed(Context &context, const CooperateEvent &event)254 void CooperateIn::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
255 {
256 FI_HILOGI("[app closed] Close all connections");
257 context.dsoftbus_.CloseAllSessions();
258 FI_HILOGI("[app closed] Stop cooperation");
259 parent_.StopCooperate(context, event);
260 }
261
OnPointerEvent(Context &context, const CooperateEvent &event)262 void CooperateIn::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
263 {
264 InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
265
266 if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
267 (filterPointerActions_.find(notice.pointerAction) != filterPointerActions_.end()) ||
268 !InputEventBuilder::IsLocalEvent(notice)) {
269 return;
270 }
271 FI_HILOGI("Stop cooperation on operation of local pointer");
272 context.OnPointerEvent(notice);
273 parent_.StopCooperate(context, event);
274 }
275
OnBoardOffline(Context &context, const CooperateEvent &event)276 void CooperateIn::Initial::OnBoardOffline(Context &context, const CooperateEvent &event)
277 {
278 DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
279
280 if (!context.IsPeer(notice.networkId)) {
281 return;
282 }
283 FI_HILOGI("[board offline] Peer(\'%{public}s\') is offline", Utility::Anonymize(notice.networkId).c_str());
284 parent_.StopCooperate(context, event);
285 }
286
OnSwitchChanged(Context &context, const CooperateEvent &event)287 void CooperateIn::Initial::OnSwitchChanged(Context &context, const CooperateEvent &event)
288 {
289 DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
290
291 if (!context.IsPeer(notice.networkId) || notice.normal) {
292 return;
293 }
294 FI_HILOGI("[switch off] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
295 parent_.StopCooperate(context, event);
296 }
297
OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)298 void CooperateIn::Initial::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
299 {
300 DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
301
302 if (!context.IsPeer(notice.networkId)) {
303 return;
304 }
305 FI_HILOGI("[softbus session closed] Disconnected with \'%{public}s\'",
306 Utility::Anonymize(notice.networkId).c_str());
307 parent_.StopCooperate(context, event);
308 context.eventMgr_.OnSoftbusSessionClosed(notice);
309 }
310
OnRemoteInputDevice(Context &context, const CooperateEvent &event)311 void CooperateIn::Initial::OnRemoteInputDevice(Context &context, const CooperateEvent &event)
312 {
313 CALL_INFO_TRACE;
314 DSoftbusSyncInputDevice notice = std::get<DSoftbusSyncInputDevice>(event.event);
315 if (!context.IsPeer(notice.networkId)) {
316 return;
317 }
318 FI_HILOGI("Remote input device from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
319 context.inputDevMgr_.AddVirtualInputDevice(notice.networkId);
320 }
321
OnRemoteHotPlug(Context &context, const CooperateEvent &event)322 void CooperateIn::Initial::OnRemoteHotPlug(Context &context, const CooperateEvent &event)
323 {
324 DSoftbusHotPlugEvent notice = std::get<DSoftbusHotPlugEvent>(event.event);
325 if (!context.IsPeer(notice.networkId)) {
326 return;
327 }
328 FI_HILOGI("Remote hot plug event from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
329 }
330
OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)331 void CooperateIn::Initial::OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)
332 {
333 UpdateCooperateFlagEvent notice = std::get<UpdateCooperateFlagEvent>(event.event);
334 uint32_t changed = (notice.mask & (context.CooperateFlag() ^ notice.flag));
335 context.UpdateCooperateFlag(notice);
336
337 if (changed & COOPERATE_FLAG_FREEZE_CURSOR) {
338 FI_HILOGI("Toggle freezing state of cursor");
339 if (notice.flag & COOPERATE_FLAG_FREEZE_CURSOR) {
340 context.inputEventBuilder_.Freeze();
341 } else {
342 context.inputEventBuilder_.Thaw();
343 }
344 }
345 }
346
OnProgress(Context &context, const CooperateEvent &event)347 void CooperateIn::Initial::OnProgress(Context &context, const CooperateEvent &event)
348 {}
349
OnReset(Context &context, const CooperateEvent &event)350 void CooperateIn::Initial::OnReset(Context &context, const CooperateEvent &event)
351 {}
352
RelayConfirmation(CooperateIn &parent, std::shared_ptr<ICooperateStep> prev)353 CooperateIn::RelayConfirmation::RelayConfirmation(CooperateIn &parent, std::shared_ptr<ICooperateStep> prev)
354 : ICooperateStep(parent, prev), parent_(parent)
355 {
356 AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
357 this->OnDisable(context, event);
358 });
359 AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
360 this->OnStop(context, event);
361 });
362 AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
363 this->OnAppClosed(context, event);
364 });
365 AddHandler(CooperateEventType::INPUT_POINTER_EVENT,
366 [this](Context &context, const CooperateEvent &event) {
367 this->OnPointerEvent(context, event);
368 });
369 AddHandler(CooperateEventType::DDM_BOARD_OFFLINE,
370 [this](Context &context, const CooperateEvent &event) {
371 this->OnBoardOffline(context, event);
372 });
373 AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
374 [this](Context &context, const CooperateEvent &event) {
375 this->OnSwitchChanged(context, event);
376 });
377 AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
378 [this](Context &context, const CooperateEvent &event) {
379 this->OnSoftbusSessionClosed(context, event);
380 });
381 AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
382 [this](Context &context, const CooperateEvent &event) {
383 this->OnResponse(context, event);
384 });
385 AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
386 [this](Context &context, const CooperateEvent &event) {
387 this->OnRemoteStart(context, event);
388 });
389 AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
390 [this](Context &context, const CooperateEvent &event) {
391 this->OnRemoteStop(context, event);
392 });
393 }
394
OnDisable(Context &context, const CooperateEvent &event)395 void CooperateIn::RelayConfirmation::OnDisable(Context &context, const CooperateEvent &event)
396 {
397 FI_HILOGI("[relay cooperate] Disable cooperation");
398 parent_.StopCooperate(context, event);
399 OnReset(context, event);
400 }
401
OnStop(Context &context, const CooperateEvent &event)402 void CooperateIn::RelayConfirmation::OnStop(Context &context, const CooperateEvent &event)
403 {
404 FI_HILOGI("[relay cooperate] Stop cooperation");
405 parent_.StopCooperate(context, event);
406 OnReset(context, event);
407
408 StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
409 parent_.UnchainConnections(context, param);
410 }
411
OnRemoteStart(Context &context, const CooperateEvent &event)412 void CooperateIn::RelayConfirmation::OnRemoteStart(Context &context, const CooperateEvent &event)
413 {
414 CALL_INFO_TRACE;
415 DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
416
417 if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
418 return;
419 }
420 FI_HILOGI("[remote start] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
421 if (parent_.process_.IsPeer(notice.networkId)) {
422 auto ret = context.Sender().Send(event);
423 if (ret != Channel<CooperateEvent>::NO_ERROR) {
424 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
425 }
426 OnReset(context, event);
427 return;
428 }
429 parent_.env_->GetTimerManager().AddTimer(DEFAULT_COOLING_TIME, REPEAT_ONCE,
430 [sender = context.Sender(), event]() mutable {
431 auto ret = sender.Send(event);
432 if (ret != Channel<CooperateEvent>::NO_ERROR) {
433 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
434 }
435 });
436 }
437
OnRemoteStop(Context &context, const CooperateEvent &event)438 void CooperateIn::RelayConfirmation::OnRemoteStop(Context &context, const CooperateEvent &event)
439 {
440 DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
441
442 if (!context.IsPeer(notice.networkId)) {
443 return;
444 }
445 FI_HILOGI("[remote stop] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
446 auto ret = context.Sender().Send(event);
447 if (ret != Channel<CooperateEvent>::NO_ERROR) {
448 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
449 }
450 OnReset(context, event);
451 }
452
OnAppClosed(Context &context, const CooperateEvent &event)453 void CooperateIn::RelayConfirmation::OnAppClosed(Context &context, const CooperateEvent &event)
454 {
455 FI_HILOGI("[app closed] Close all connections");
456 context.dsoftbus_.CloseAllSessions();
457 FI_HILOGI("[relay cooperate] Stop cooperation on app closed");
458 parent_.StopCooperate(context, event);
459 OnReset(context, event);
460 }
461
OnPointerEvent(Context &context, const CooperateEvent &event)462 void CooperateIn::RelayConfirmation::OnPointerEvent(Context &context, const CooperateEvent &event)
463 {
464 InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
465
466 if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
467 !InputEventBuilder::IsLocalEvent(notice)) {
468 return;
469 }
470 FI_HILOGI("[relay cooperate] Stop cooperation on operation of local pointer");
471 context.OnPointerEvent(notice);
472 parent_.StopCooperate(context, event);
473 OnReset(context, event);
474 }
475
OnBoardOffline(Context &context, const CooperateEvent &event)476 void CooperateIn::RelayConfirmation::OnBoardOffline(Context &context, const CooperateEvent &event)
477 {
478 DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
479
480 if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
481 return;
482 }
483 FI_HILOGI("[relay cooperate] Peer(%{public}s) is offline", Utility::Anonymize(notice.networkId).c_str());
484 if (context.IsPeer(notice.networkId)) {
485 parent_.StopCooperate(context, event);
486 }
487 OnReset(context, event);
488 }
489
OnSwitchChanged(Context &context, const CooperateEvent &event)490 void CooperateIn::RelayConfirmation::OnSwitchChanged(Context &context, const CooperateEvent &event)
491 {
492 DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
493
494 if (notice.normal ||
495 (!context.IsPeer(notice.networkId) &&
496 !parent_.process_.IsPeer(notice.networkId))) {
497 return;
498 }
499 FI_HILOGI("[relay cooperate] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
500 if (context.IsPeer(notice.networkId)) {
501 parent_.StopCooperate(context, event);
502 }
503 OnReset(context, event);
504 }
505
OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)506 void CooperateIn::RelayConfirmation::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
507 {
508 DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
509
510 if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
511 return;
512 }
513 FI_HILOGI("[relay cooperate] Disconnected with \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
514 if (context.IsPeer(notice.networkId)) {
515 parent_.StopCooperate(context, event);
516 }
517 OnReset(context, event);
518 }
519
OnResponse(Context &context, const CooperateEvent &event)520 void CooperateIn::RelayConfirmation::OnResponse(Context &context, const CooperateEvent &event)
521 {
522 DSoftbusRelayCooperateFinished notice = std::get<DSoftbusRelayCooperateFinished>(event.event);
523
524 if (!context.IsPeer(notice.networkId)) {
525 return;
526 }
527 FI_HILOGI("[relay cooperate] \'%{public}s\' respond", Utility::Anonymize(notice.networkId).c_str());
528 parent_.env_->GetTimerManager().RemoveTimer(timerId_);
529 if (notice.normal) {
530 OnNormal(context, event);
531 Proceed(context, event);
532 } else {
533 OnReset(context, event);
534 }
535 }
536
OnNormal(Context &context, const CooperateEvent &event)537 void CooperateIn::RelayConfirmation::OnNormal(Context &context, const CooperateEvent &event)
538 {
539 FI_HILOGI("[relay cooperate] Cooperation with \'%{public}s\' established",
540 Utility::Anonymize(parent_.process_.Peer()).c_str());
541 context.inputEventBuilder_.Disable();
542
543 DSoftbusStartCooperate notice {
544 .originNetworkId = context.Peer(),
545 .success = true,
546 .cursorPos = context.NormalizedCursorPosition(),
547 };
548 context.OnStartCooperate(notice.extra);
549 context.dsoftbus_.StartCooperate(parent_.process_.Peer(), notice);
550
551 context.eventMgr_.StartCooperateFinish(notice);
552 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
553 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
554 context.OnRelayCooperation(parent_.process_.Peer(), context.NormalizedCursorPosition());
555 }
556
OnProgress(Context &context, const CooperateEvent &event)557 void CooperateIn::RelayConfirmation::OnProgress(Context &context, const CooperateEvent &event)
558 {
559 std::string remoteNetworkId = parent_.process_.Peer();
560 FI_HILOGI("[relay cooperate] Connect \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
561 int32_t ret = context.dsoftbus_.OpenSession(remoteNetworkId);
562 if (ret != RET_OK) {
563 FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
564 OnReset(context, event);
565 return;
566 }
567
568 FI_HILOGI("[relay cooperate] Notify origin(\'%{public}s\')", Utility::Anonymize(context.Peer()).c_str());
569 DSoftbusRelayCooperate notice {
570 .targetNetworkId = parent_.process_.Peer(),
571 };
572 context.dsoftbus_.RelayCooperate(context.Peer(), notice);
573
574 timerId_ = parent_.env_->GetTimerManager().AddTimer(DEFAULT_TIMEOUT, REPEAT_ONCE,
575 [sender = context.Sender(), remoteNetworkId = context.Peer()]() mutable {
576 auto ret = sender.Send(CooperateEvent(
577 CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
578 DSoftbusRelayCooperateFinished {
579 .networkId = remoteNetworkId,
580 .normal = false,
581 }));
582 if (ret != Channel<CooperateEvent>::NO_ERROR) {
583 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
584 }
585 });
586 }
587
OnReset(Context &context, const CooperateEvent &event)588 void CooperateIn::RelayConfirmation::OnReset(Context &context, const CooperateEvent &event)
589 {
590 FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
591 Utility::Anonymize(parent_.process_.Peer()).c_str());
592 DSoftbusStartCooperateFinished result {
593 .success = false
594 };
595 context.eventMgr_.StartCooperateFinish(result);
596 Reset(context, event);
597 }
598
StopCooperate(Context &context, const CooperateEvent &event)599 void CooperateIn::StopCooperate(Context &context, const CooperateEvent &event)
600 {
601 FI_HILOGI("Stop cooperation with \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
602 context.inputEventBuilder_.Disable();
603 context.UpdateCursorPosition();
604
605 DSoftbusStopCooperate notice {};
606 context.dsoftbus_.StopCooperate(context.Peer(), notice);
607 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
608 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
609 context.OnResetCooperation();
610 SetPointerVisible(context);
611 }
612
SetPointerVisible(Context &context)613 void CooperateIn::SetPointerVisible(Context &context)
614 {
615 CHKPV(env_);
616 bool hasLocalPointerDevice = env_->GetDeviceManager().HasLocalPointerDevice();
617 env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
618 }
619
UnchainConnections(Context &context, const StopCooperateEvent &event) const620 void CooperateIn::UnchainConnections(Context &context, const StopCooperateEvent &event) const
621 {
622 if (event.isUnchained) {
623 FI_HILOGI("Unchain all connections");
624 context.dsoftbus_.CloseAllSessions();
625 context.eventMgr_.OnUnchain(event);
626 }
627 }
628 } // namespace Cooperate
629 } // namespace DeviceStatus
630 } // namespace Msdp
631 } // namespace OHOS
632