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