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.OnRemoteStartCooperate(notice.extra);
225 context.eventMgr_.RemoteStart(notice);
226
227 DSoftbusStopCooperate stopNotice {};
228 context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
229
230 context.RemoteStartSuccess(notice);
231 context.inputEventBuilder_.Update(context);
232 context.eventMgr_.RemoteStartFinish(notice);
233 FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
234 context.OnTransitionIn();
235 }
236
OnRemoteStop(Context & context,const CooperateEvent & event)237 void CooperateIn::Initial::OnRemoteStop(Context &context, const CooperateEvent &event)
238 {
239 DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
240
241 if (!context.IsPeer(notice.networkId)) {
242 return;
243 }
244 FI_HILOGI("[remote stop] Notification from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
245 context.eventMgr_.RemoteStop(notice);
246 context.inputEventBuilder_.Disable();
247 context.eventMgr_.RemoteStopFinish(notice);
248 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
249 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
250 context.OnResetCooperation();
251 }
252
OnAppClosed(Context & context,const CooperateEvent & event)253 void CooperateIn::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
254 {
255 FI_HILOGI("[app closed] Close all connections");
256 context.dsoftbus_.CloseAllSessions();
257 FI_HILOGI("[app closed] Stop cooperation");
258 parent_.StopCooperate(context, event);
259 }
260
OnPointerEvent(Context & context,const CooperateEvent & event)261 void CooperateIn::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
262 {
263 InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
264
265 if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
266 (filterPointerActions_.find(notice.pointerAction) != filterPointerActions_.end()) ||
267 !InputEventBuilder::IsLocalEvent(notice)) {
268 return;
269 }
270 FI_HILOGI("Stop cooperation on operation of local pointer");
271 context.OnPointerEvent(notice);
272 parent_.StopCooperate(context, event);
273 }
274
OnBoardOffline(Context & context,const CooperateEvent & event)275 void CooperateIn::Initial::OnBoardOffline(Context &context, const CooperateEvent &event)
276 {
277 DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
278
279 if (!context.IsPeer(notice.networkId)) {
280 return;
281 }
282 FI_HILOGI("[board offline] Peer(\'%{public}s\') is offline", Utility::Anonymize(notice.networkId).c_str());
283 parent_.StopCooperate(context, event);
284 }
285
OnSwitchChanged(Context & context,const CooperateEvent & event)286 void CooperateIn::Initial::OnSwitchChanged(Context &context, const CooperateEvent &event)
287 {
288 DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
289
290 if (!context.IsPeer(notice.networkId) || notice.normal) {
291 return;
292 }
293 FI_HILOGI("[switch off] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
294 parent_.StopCooperate(context, event);
295 }
296
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)297 void CooperateIn::Initial::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
298 {
299 DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
300
301 if (!context.IsPeer(notice.networkId)) {
302 return;
303 }
304 FI_HILOGI("[softbus session closed] Disconnected with \'%{public}s\'",
305 Utility::Anonymize(notice.networkId).c_str());
306 parent_.StopCooperate(context, event);
307 context.eventMgr_.OnSoftbusSessionClosed(notice);
308 }
309
OnRemoteInputDevice(Context & context,const CooperateEvent & event)310 void CooperateIn::Initial::OnRemoteInputDevice(Context &context, const CooperateEvent &event)
311 {
312 CALL_INFO_TRACE;
313 DSoftbusSyncInputDevice notice = std::get<DSoftbusSyncInputDevice>(event.event);
314 if (!context.IsPeer(notice.networkId)) {
315 return;
316 }
317 FI_HILOGI("Remote input device from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
318 context.inputDevMgr_.AddVirtualInputDevice(notice.networkId);
319 }
320
OnRemoteHotPlug(Context & context,const CooperateEvent & event)321 void CooperateIn::Initial::OnRemoteHotPlug(Context &context, const CooperateEvent &event)
322 {
323 DSoftbusHotPlugEvent notice = std::get<DSoftbusHotPlugEvent>(event.event);
324 if (!context.IsPeer(notice.networkId)) {
325 return;
326 }
327 FI_HILOGI("Remote hot plug event from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
328 }
329
OnUpdateCooperateFlag(Context & context,const CooperateEvent & event)330 void CooperateIn::Initial::OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)
331 {
332 UpdateCooperateFlagEvent notice = std::get<UpdateCooperateFlagEvent>(event.event);
333 uint32_t changed = (notice.mask & (context.CooperateFlag() ^ notice.flag));
334 context.UpdateCooperateFlag(notice);
335
336 if (changed & COOPERATE_FLAG_FREEZE_CURSOR) {
337 FI_HILOGI("Toggle freezing state of cursor");
338 if (notice.flag & COOPERATE_FLAG_FREEZE_CURSOR) {
339 context.inputEventBuilder_.Freeze();
340 } else {
341 context.inputEventBuilder_.Thaw();
342 }
343 }
344 }
345
OnProgress(Context & context,const CooperateEvent & event)346 void CooperateIn::Initial::OnProgress(Context &context, const CooperateEvent &event)
347 {}
348
OnReset(Context & context,const CooperateEvent & event)349 void CooperateIn::Initial::OnReset(Context &context, const CooperateEvent &event)
350 {}
351
RelayConfirmation(CooperateIn & parent,std::shared_ptr<ICooperateStep> prev)352 CooperateIn::RelayConfirmation::RelayConfirmation(CooperateIn &parent, std::shared_ptr<ICooperateStep> prev)
353 : ICooperateStep(parent, prev), parent_(parent)
354 {
355 AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
356 this->OnDisable(context, event);
357 });
358 AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
359 this->OnStop(context, event);
360 });
361 AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
362 this->OnAppClosed(context, event);
363 });
364 AddHandler(CooperateEventType::INPUT_POINTER_EVENT,
365 [this](Context &context, const CooperateEvent &event) {
366 this->OnPointerEvent(context, event);
367 });
368 AddHandler(CooperateEventType::DDM_BOARD_OFFLINE,
369 [this](Context &context, const CooperateEvent &event) {
370 this->OnBoardOffline(context, event);
371 });
372 AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
373 [this](Context &context, const CooperateEvent &event) {
374 this->OnSwitchChanged(context, event);
375 });
376 AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
377 [this](Context &context, const CooperateEvent &event) {
378 this->OnSoftbusSessionClosed(context, event);
379 });
380 AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
381 [this](Context &context, const CooperateEvent &event) {
382 this->OnResponse(context, event);
383 });
384 AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
385 [this](Context &context, const CooperateEvent &event) {
386 this->OnRemoteStart(context, event);
387 });
388 AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
389 [this](Context &context, const CooperateEvent &event) {
390 this->OnRemoteStop(context, event);
391 });
392 }
393
OnDisable(Context & context,const CooperateEvent & event)394 void CooperateIn::RelayConfirmation::OnDisable(Context &context, const CooperateEvent &event)
395 {
396 FI_HILOGI("[relay cooperate] Disable cooperation");
397 parent_.StopCooperate(context, event);
398 OnReset(context, event);
399 }
400
OnStop(Context & context,const CooperateEvent & event)401 void CooperateIn::RelayConfirmation::OnStop(Context &context, const CooperateEvent &event)
402 {
403 FI_HILOGI("[relay cooperate] Stop cooperation");
404 parent_.StopCooperate(context, event);
405 OnReset(context, event);
406
407 StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
408 parent_.UnchainConnections(context, param);
409 }
410
OnRemoteStart(Context & context,const CooperateEvent & event)411 void CooperateIn::RelayConfirmation::OnRemoteStart(Context &context, const CooperateEvent &event)
412 {
413 CALL_INFO_TRACE;
414 DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
415
416 if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
417 return;
418 }
419 FI_HILOGI("[remote start] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
420 if (parent_.process_.IsPeer(notice.networkId)) {
421 auto ret = context.Sender().Send(event);
422 if (ret != Channel<CooperateEvent>::NO_ERROR) {
423 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
424 }
425 OnReset(context, event);
426 return;
427 }
428 parent_.env_->GetTimerManager().AddTimer(DEFAULT_COOLING_TIME, REPEAT_ONCE,
429 [sender = context.Sender(), event]() mutable {
430 auto ret = sender.Send(event);
431 if (ret != Channel<CooperateEvent>::NO_ERROR) {
432 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
433 }
434 });
435 }
436
OnRemoteStop(Context & context,const CooperateEvent & event)437 void CooperateIn::RelayConfirmation::OnRemoteStop(Context &context, const CooperateEvent &event)
438 {
439 DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
440
441 if (!context.IsPeer(notice.networkId)) {
442 return;
443 }
444 FI_HILOGI("[remote stop] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
445 auto ret = context.Sender().Send(event);
446 if (ret != Channel<CooperateEvent>::NO_ERROR) {
447 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
448 }
449 OnReset(context, event);
450 }
451
OnAppClosed(Context & context,const CooperateEvent & event)452 void CooperateIn::RelayConfirmation::OnAppClosed(Context &context, const CooperateEvent &event)
453 {
454 FI_HILOGI("[app closed] Close all connections");
455 context.dsoftbus_.CloseAllSessions();
456 FI_HILOGI("[relay cooperate] Stop cooperation on app closed");
457 parent_.StopCooperate(context, event);
458 OnReset(context, event);
459 }
460
OnPointerEvent(Context & context,const CooperateEvent & event)461 void CooperateIn::RelayConfirmation::OnPointerEvent(Context &context, const CooperateEvent &event)
462 {
463 InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
464
465 if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
466 !InputEventBuilder::IsLocalEvent(notice)) {
467 return;
468 }
469 FI_HILOGI("[relay cooperate] Stop cooperation on operation of local pointer");
470 context.OnPointerEvent(notice);
471 parent_.StopCooperate(context, event);
472 OnReset(context, event);
473 }
474
OnBoardOffline(Context & context,const CooperateEvent & event)475 void CooperateIn::RelayConfirmation::OnBoardOffline(Context &context, const CooperateEvent &event)
476 {
477 DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
478
479 if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
480 return;
481 }
482 FI_HILOGI("[relay cooperate] Peer(%{public}s) is offline", Utility::Anonymize(notice.networkId).c_str());
483 if (context.IsPeer(notice.networkId)) {
484 parent_.StopCooperate(context, event);
485 }
486 OnReset(context, event);
487 }
488
OnSwitchChanged(Context & context,const CooperateEvent & event)489 void CooperateIn::RelayConfirmation::OnSwitchChanged(Context &context, const CooperateEvent &event)
490 {
491 DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
492
493 if (notice.normal ||
494 (!context.IsPeer(notice.networkId) &&
495 !parent_.process_.IsPeer(notice.networkId))) {
496 return;
497 }
498 FI_HILOGI("[relay cooperate] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
499 if (context.IsPeer(notice.networkId)) {
500 parent_.StopCooperate(context, event);
501 }
502 OnReset(context, event);
503 }
504
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)505 void CooperateIn::RelayConfirmation::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
506 {
507 DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
508
509 if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
510 return;
511 }
512 FI_HILOGI("[relay cooperate] Disconnected with \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
513 if (context.IsPeer(notice.networkId)) {
514 parent_.StopCooperate(context, event);
515 }
516 OnReset(context, event);
517 }
518
OnResponse(Context & context,const CooperateEvent & event)519 void CooperateIn::RelayConfirmation::OnResponse(Context &context, const CooperateEvent &event)
520 {
521 DSoftbusRelayCooperateFinished notice = std::get<DSoftbusRelayCooperateFinished>(event.event);
522
523 if (!context.IsPeer(notice.networkId)) {
524 return;
525 }
526 FI_HILOGI("[relay cooperate] \'%{public}s\' respond", Utility::Anonymize(notice.networkId).c_str());
527 parent_.env_->GetTimerManager().RemoveTimer(timerId_);
528 if (notice.normal) {
529 OnNormal(context, event);
530 Proceed(context, event);
531 } else {
532 OnReset(context, event);
533 }
534 }
535
OnNormal(Context & context,const CooperateEvent & event)536 void CooperateIn::RelayConfirmation::OnNormal(Context &context, const CooperateEvent &event)
537 {
538 FI_HILOGI("[relay cooperate] Cooperation with \'%{public}s\' established",
539 Utility::Anonymize(parent_.process_.Peer()).c_str());
540 context.inputEventBuilder_.Disable();
541
542 DSoftbusStartCooperate notice {
543 .originNetworkId = context.Peer(),
544 .success = true,
545 .cursorPos = context.NormalizedCursorPosition(),
546 };
547 context.OnStartCooperate(notice.extra);
548 context.dsoftbus_.StartCooperate(parent_.process_.Peer(), notice);
549
550 context.eventMgr_.StartCooperateFinish(notice);
551 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
552 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
553 context.OnRelayCooperation(parent_.process_.Peer(), context.NormalizedCursorPosition());
554 }
555
OnProgress(Context & context,const CooperateEvent & event)556 void CooperateIn::RelayConfirmation::OnProgress(Context &context, const CooperateEvent &event)
557 {
558 std::string remoteNetworkId = parent_.process_.Peer();
559 FI_HILOGI("[relay cooperate] Connect \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
560 int32_t ret = context.dsoftbus_.OpenSession(remoteNetworkId);
561 if (ret != RET_OK) {
562 FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
563 OnReset(context, event);
564 return;
565 }
566
567 FI_HILOGI("[relay cooperate] Notify origin(\'%{public}s\')", Utility::Anonymize(context.Peer()).c_str());
568 DSoftbusRelayCooperate notice {
569 .targetNetworkId = parent_.process_.Peer(),
570 };
571 context.dsoftbus_.RelayCooperate(context.Peer(), notice);
572
573 timerId_ = parent_.env_->GetTimerManager().AddTimer(DEFAULT_TIMEOUT, REPEAT_ONCE,
574 [sender = context.Sender(), remoteNetworkId = context.Peer()]() mutable {
575 auto ret = sender.Send(CooperateEvent(
576 CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
577 DSoftbusRelayCooperateFinished {
578 .networkId = remoteNetworkId,
579 .normal = false,
580 }));
581 if (ret != Channel<CooperateEvent>::NO_ERROR) {
582 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
583 }
584 });
585 }
586
OnReset(Context & context,const CooperateEvent & event)587 void CooperateIn::RelayConfirmation::OnReset(Context &context, const CooperateEvent &event)
588 {
589 FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
590 Utility::Anonymize(parent_.process_.Peer()).c_str());
591 DSoftbusStartCooperateFinished result {
592 .success = false
593 };
594 context.eventMgr_.StartCooperateFinish(result);
595 Reset(context, event);
596 }
597
StopCooperate(Context & context,const CooperateEvent & event)598 void CooperateIn::StopCooperate(Context &context, const CooperateEvent &event)
599 {
600 FI_HILOGI("Stop cooperation with \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
601 context.inputEventBuilder_.Disable();
602 context.UpdateCursorPosition();
603
604 DSoftbusStopCooperate notice {};
605 context.dsoftbus_.StopCooperate(context.Peer(), notice);
606 context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
607 TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
608 context.OnResetCooperation();
609 SetPointerVisible(context);
610 }
611
SetPointerVisible(Context & context)612 void CooperateIn::SetPointerVisible(Context &context)
613 {
614 CHKPV(env_);
615 bool hasLocalPointerDevice = env_->GetDeviceManager().HasLocalPointerDevice();
616 env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
617 }
618
UnchainConnections(Context & context,const StopCooperateEvent & event) const619 void CooperateIn::UnchainConnections(Context &context, const StopCooperateEvent &event) const
620 {
621 if (event.isUnchained) {
622 FI_HILOGI("Unchain all connections");
623 context.dsoftbus_.CloseAllSessions();
624 context.eventMgr_.OnUnchain(event);
625 }
626 }
627 } // namespace Cooperate
628 } // namespace DeviceStatus
629 } // namespace Msdp
630 } // namespace OHOS
631