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