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